try {
(function(){
	window['query'] = function(_cm) {
		var order=[];
		var selection=[];
		var from=[];
		var criteria=[];
		var limit=[];
		var result=[];
		var cm = _cm
		/**
		// valid format for parameter a is
		// [int,int,int...]
		// each number for zero based index number to select from the from array
		*/
		this.select = function(a) {
			if (a instanceof Array) {
				selection = a;
			} else {
				alert("The argument for 'select' function must be an Array");
			}
			return this;
		}
		/**
		// valid format for parameter a is Array
		*/
		this.from = function(a) {
			if (a instanceof Array) {
				from = a;
			} else {
				alert("The argument for 'select' function must be an Array");
			}
			return this;
		}
		/**
		// valid format for parameter a is
		// [[[and1],[and2],...], [[or1],[or2],...]]
		// each criteria is in the following format:
		// ["index", "compare method","value"]
		// index is the zero based number of the column index of from array
		// compare methods maybe one of the following:
		// "eq", "gt", "lt", "gteq", "lteq"....
		*/
		this.where = function(a) {
			if (a instanceof Array) {
				criteria = a;
			} else {
				alert("The argument for 'select' function must be an Array");
			}
			return this;
		}
		/**
		// valid format for parameter a is
		// ["index","sort method"]
		// index is the zero based number of the column index of the from array which the sort action depends on
		// sort method may be one of the following:
		// "desc", "asc"
		*/
		this.orderby = function(a) {
			if (a instanceof Array) {
				order = a;
			} else {
				alert("The argument for 'select' function must be an Array");
			}
			return this;
		}
		/**
		// valid format for paramater a is
		// ["start", "limit"]
		// where start is the zero based index of the from array the result array start
		// and the limit is the length of the result array
		*/
		this.limit = function(a) {
			if (a instanceof Array) {
				limit = a;
			} else {
				alert("The argument for 'select' function must be an Array");
			}
			return this;
		}
		function comp(a,b) {
			var col = 0;
			for(var i=0; i<selection.length; i++) {
				if(selection[i] == order[0]) col = i;
			}
			if(!isNaN(a[col]) || !isNaN(b[col])) {
				return (order[1]=="asc")? a[col]-b[col]:0-a[col]+b[col];
			}else{
				var factor = 10;
				var tmp1 = a[col].toString();
				var tmp2 = b[col].toString();
				var r1 = 0;
				var r2 = 0;
				var n1 = (tmp1.length>factor)? factor:tmp1.length;
				var n2 = (tmp2.length>factor)? factor:tmp2.length;
				for(var m=0; m<n1; m++) {
					r1 = r1*32 + tmp1.charCodeAt(m);
				}
				for(var m=0; m<n2; m++) {
					r2 = r2*32 + tmp2.charCodeAt(m);
				}
				return (order[1]=="asc")? r1-r2:0-r1+r2;
			}
		}
		/**
		// the final treatment function
		// the flow is as the following:
		// 1. prepare to treat each item of the from array
		// 2. if no criteria, then put the "selection" fields into ret array
		// 3. if there're criterias, then do the following treatment:
		// 		3.1. sum up the "AND" criteria and the result in selornot1
		//      3.2. sum up the "OR" criteria and the result in selornot2
		//      3.3. determin the result by combine the two result using "OR" logic
		// 4. sort the ret array according to the "order" condition
		// 5. return the ret array as result
		*/
		this.exec = function() {
			result = [];
			if(!selection.length>0) {
				return [];
			}
			if(!from.length>0) {
				return [];
			}
			var ret = [];
			// step 1.
			for(var i=0; i<from.length; i++) {
				// step 2.
				if(criteria.length==0) {
					var tmp = [];
					if(selection.length==1 || selection[0] == "*") {
						tmp = from[i];
					} else {
						for(var j in selection) {
							tmp.push(from[i][selection[j]]);
						}
					}
					ret.push(tmp);
				// step 3.
				} else {
					// if there're existing criterias...
					for(var i=0; i<from.length; i++) {
						//tranversing all AND criteria to determin which row to add to the result set
						//to speed up the query, any "FALSE" condition will force the loop to stop and give the result to "FALSE"
						var selornot1 = false;
						// 3.1
						if(criteria.length > 0) {
							for(var m=0; m<criteria[0].length; m++) {
								if(cm[criteria[0][m][1]]!==undefined) {
									selornot1 = cm[criteria[0][m][1]](from[i][criteria[0][m][0]], criteria[0][m][2]);
									if(!selornot1) break;
								}
							}
						}
						//tranversing all AND criteria to determin which row to add to the result set
						//to speed up the query, any "TRUE" condition will force the loop to stop and give the result to "TRUE"
						var selornot2 = false;
						// 3.2
						if(criteria.length > 1) {
							for(var m=0; m<criteria[1].length; m++){
								if(cm[criteria[1][m][1]]!==undefined) {
									selornot2 = cm[criteria[1][m][1]](from[i][criteria[1][m][0]], criteria[1][m][2]);
									if(selornot2) break;
								}
							}
						}
						// 3.3
						if(selornot1 || selornot2) {
							var tmp = [];
							if(selection.length==1 || selection[0] == "*") {
								tmp = from[i];
							} else {
								for(var j in selection) {
									tmp.push(from[i][selection[j]]);
								}
							}
							ret.push(tmp);
						}
					}
				}
			}
			// step 4.
			if(order.length > 0) {
				ret.sort(comp);
			}
			// step 5.
			if(limit.length>0) {
				result = ret.slice(limit[0],limit[0]+limit[1]);
				return ret.slice(limit[0],limit[0]+limit[1]);
			} else {
				result = ret;
				return ret;
			}
		}
		this.result = function() {
			return result;
		}
		this.count = function() {
			return result.length;
		}
		this.test = function() {
			alert(selection);
			alert(from);
			alert(criteria);
			alert(order);
			alert(limit);
		}
	}
	var cm = {
		"eq": function(a,b) {
			if(a==b) return true;
			return false;
		},
		"gt": function(a,b) {
			if(a>b) return true;
			return false;
		},
		"lt": function(a,b) {
			if(a<b) return true;
			return false;
		},
		"gteq": function(a,b) {
			if(a>=b) return true;
			return false;
		},
		"lteq": function(a,b) {
			if(a<=b) return true;
			return false;
		}
	};
	window['getquery'] = function() {
		return new query(cm);
	}
})();
}catch(e){alert(e);}