function QueryBlockClass(keyword, tld) {
	this.readyState = 0;
	this.hits = 0;
	this.pop = 0;
	
	this.hitsRank = 0;
	this.popRank = 0;
	
	this.keyword = keyword;
	this.tld = tld;
}

function QueryBlockClassMulti(keyword, tld, x, y) {
	this.readyState = 0;
	this.hits = 0;
	
	this.hitsRank = 0;
	
	this.keyword = keyword;
	this.tld = tld;
	this.x = x;
	this.y = y;
}

function QueryBlockClassAdvanced(keyword, tld, language, location, filetype, howrecent, wip, x, y) {
	this.readyState = 0;
	this.hits = 0;
	
	this.hitsRank = 0;
	
	this.keyword = keyword;
	this.tld = tld;
	this.language = language;
	this.location = location;
	this.filetype = filetype;
	this.howrecent = howrecent;
	this.wip = wip;
	
	this.x = x;
	this.y = y;
}

function KeywordClass(value) {
	this.value = value;
}

function QueryTldClass(value) {
	this.value = value;
}

var query = new function() {
	this.data = false;
	this.keywords = false;
	this.tlds = false;
	this.columns = false;
	this.cancel = true;
	this.baseResults = 0;
	this.processing = false;
	this.tld_all = false;
	
	var server = "query.php";
	var clusterSize = 10;
	var postInterval = 500;
	var startTime = 0;
	var queryMode = false;
	
	/* Basic query aanmaken */
	this.createBasicQuery = function(keyword, tld_all) {
		var i, rows, temp;
		
		queryMode = "basic";
		this.data = Array();
		this.keywords = Array();
		this.keywords[0] = new KeywordClass(keyword);
		this.tld_all = tld_all;
		
		rows = (tld_all) ? data.tlds.length : 51;
		for (i = 1; i < rows; i++) {
			this.data[i - 1] = new QueryBlockClass(this.keywords[0], data.tlds[i]);
		}
		
		return true;
	}
	
	/* Multisplit query aanmaken */
	this.createMultiQuery = function(keywords, tlds) {
		var i, c, key, roi;
		
		queryMode = "multi";
		this.data = Array();
		this.keywords = Array();
		for (i = 0; i < keywords.length; i++) {
			this.keywords[i] = new KeywordClass(keywords[i]);
		}
		this.tlds = Array();
		for (i = 0; i < tlds.length; i++) {
			this.tlds[i] = new QueryTldClass(tlds[i]);
		}
		
		roi = new KeywordClass("");
		key = 0;
		for (i = 0; i < this.keywords.length; i++) {
			for (c = 0; c < this.tlds.length; c++) {
				this.data[key++] = new QueryBlockClassMulti(this.keywords[i], this.tlds[c], i, c);
			}
			this.data[key++] = new QueryBlockClassMulti(this.keywords[i], roi, i, c);
		}
		return true;
	}
	
	/* Advanced query aanmaken */
	this.createAdvancedQuery = function(keywords, tlds, languages, locations, filetypes, howrecents, wips) {
		var i, c, key, a, b, c, d, e, f, g, multiTabel, roi;
		this.columns = Array(Array("KEYWORD", true), Array("DOMAIN", true), Array("LANGUAGE", true), Array("LOCATION", true), Array("FILETYPE", true), Array("HOW RECENT", true), Array("WHERE IN PAGE", true), Array("HITS", true));
		multiTabel = false;
		
		queryMode = "advanced";
		this.data = Array();
		/* Keywords */
		this.keywords = Array();
		for (i = 0; i < keywords.length; i++) {
			this.keywords[i] = new KeywordClass(keywords[i]);
		}
		if (keywords.length == 0) {this.keywords[0] = false; this.columns[0][1] = false; }
		/* Domains */
		this.tlds = Array();
		for (i = 0; i < tlds.length; i++) {
			this.tlds[i] = new QueryTldClass(tlds[i]);
		}
		if (tlds.length == 0) {this.tlds[0] = false; this.columns[1][1] = false; }
		/* Rest */
		this.advancedData.languages = languages;
		this.advancedData.locations = locations;
		this.advancedData.filetypes = filetypes;
		this.advancedData.howrecents = howrecents;
		this.advancedData.wips = wips;
		if (languages.length == 0) {languages[0] = false; this.columns[2][1] = false; }
		if (locations.length == 0) {locations[0] = false; this.columns[3][1] = false; }
		if (filetypes.length == 0) {filetypes[0] = false; this.columns[4][1] = false; }
		if (howrecents.length == 0) {howrecents[0] = false; this.columns[5][1] = false; }
		if (wips.length == 0) {wips[0] = false; this.columns[6][1] = false; }
		if (!languages[0] && !locations[0] && !filetypes[0] && !howrecents[0] && !wips[0]) multiTabel = true;
		
		roi = new KeywordClass("");
		key = 0;
		for (a = 0; a < this.keywords.length; a++) {
			for (b = 0; b < this.tlds.length; b++) {
				for (c = 0; c < languages.length; c++) {
					for (d = 0; d < locations.length; d++) {
						for (e = 0; e < filetypes.length; e++) {
							for (f = 0; f < howrecents.length; f++) {
								for (g = 0; g < wips.length; g++) {
									this.data[key++] = new QueryBlockClassAdvanced(this.keywords[a], this.tlds[b], languages[c], locations[d], filetypes[e], howrecents[f], wips[g], a, b);
								}
							}
						}
					}
				}
			}
			if (multiTabel) this.data[key++] = new QueryBlockClassAdvanced(this.keywords[a], roi, languages[c], locations[d], filetypes[e], howrecents[f], wips[g], a, b);
		}
		return true;
	}
	this.advancedData = new function() {
		this.languages = Array();
		this.locations = Array();
		this.filetypes = Array();
		this.howrecents = Array();
		this.wips = Array();
	}
	
	/* Query's uitvoeren */
	this.execute = function() {
		var buffer, request;
		this.cancel = false;
		this.processing = true;
		startTime = (new Date()).getTime();
		
		if (queryMode == "basic") {
    		buffer = server + "?data[]=" + this.data[0].keyword.value + "&r=" + Math.random();
    		request = httpRequest();
    		request.onreadystatechange = function() {
    			if (request.readyState == 4) {
    				var data;
    				eval("data = " + request.responseText);
    				if (data) {
    					query.baseResults = data.results[0].hits;
    				}
    				else {
    					query.baseResults = 0;
    				}
    			}
    		}
    		request.open("GET", buffer, true);
    		request.send(null);
		}
		
		if (this.data) {
			this.sendCluster();
		}
		else {
			return false;
		}
	}
	
	this.sendCluster = function() {
		if (this.cancel) return false;
		var i, c, buffer, request;
		c = 0;
		buffer = "";
		
		if (queryMode == "basic") {
    		for (i = 0; i < this.data.length && c < clusterSize; i++) {
    			if (this.data[i].readyState == 0) {
    				this.data[i].readyState = 1;
    				buffer += "&data[]=" + i + "|" + this.data[i].keyword.value + "|." + this.data[i].tld.tld;
    				c++;
    			}
    		}
		}
		else if (queryMode == "multi") {
    		for (i = 0; i < this.data.length && c < clusterSize; i++) {
    			if (this.data[i].readyState == 0) {
    				this.data[i].readyState = 1;
    				buffer += "&data[]=" + i + "|" + this.data[i].keyword.value + "|" + this.data[i].tld.value;
    				c++;
    			}
    		}
		}
		else if (queryMode == "advanced") {
    		for (i = 0; i < this.data.length && c < clusterSize; i++) {
    			if (this.data[i].readyState == 0) {
    				this.data[i].readyState = 1;
    				buffer += "&data[]=" + i;
					buffer += "|" + ((this.data[i].keyword) ? this.data[i].keyword.value : "");
					buffer += "|" + ((this.data[i].tld) ? this.data[i].tld.value : "");
					buffer += "|" + ((this.data[i].language) ? this.data[i].language.code : "");
					buffer += "|" + ((this.data[i].location) ? this.data[i].location.code : "");
					buffer += "|" + ((this.data[i].filetype) ? this.data[i].filetype.ext : "");
					buffer += "|" + ((this.data[i].howrecent) ? this.data[i].howrecent.code : "");
					buffer += "|" + ((this.data[i].wip) ? this.data[i].wip.code : "");
    				c++;
    			}
    		}
		}
		
		if (c > 0) {
			buffer = server + "?c=" + c + buffer + "&r=" + Math.random();
			request = httpRequest();
			if (queryMode == "basic") {
    			request.onreadystatechange = function() {
    				if (request.readyState == 4) {
    					if (query.cancel) return false;
    					var i, data, handle, result, results;
    					results = Array();
    					eval("data = " + request.responseText);
    					if (data) {
    						for (i = 0; i < data.results.length; i++) {
    							result = data.results[i];
    							handle = query.data[result.id];
    							if (handle) {
    								if (handle.readyState == 1) {
    									handle.readyState = 2;
    									handle.hits = result.hits;
    									handle.pop = (handle.tld.hits == 0) ? 0 : handle.hits / handle.tld.hits * 10000;
    									results[results.length] = handle;
    								}
    							}
    						}
    						onQueryData(results);
							for (i = 0; i < query.data.length; i++) {
								if (query.data[i].readyState != 2) {
									i = 99999;
								}
							}
							if (i < 99999) onQueryExecuted();
    					}
    				}
    			}
			}
			if (queryMode == "multi") {
    			request.onreadystatechange = function() {
    				if (request.readyState == 4) {
    					if (query.cancel) return false;
    					var i, data, handle, result, results;
    					results = Array();
    					eval("data = " + request.responseText);
    					if (data) {
    						for (i = 0; i < data.results.length; i++) {
    							result = data.results[i];
    							handle = query.data[result.id];
    							if (handle) {
    								if (handle.readyState == 1) {
    									handle.readyState = 2;
    									handle.hits = result.hits;
    									results[results.length] = handle;
    								}
    							}
    						}
    						onQueryData(results);
							for (i = 0; i < query.data.length; i++) {
								if (query.data[i].readyState != 2) {
									i = 99999;
								}
							}
							if (i < 99999) onQueryExecuted();
    					}
    				}
    			}
			}
			if (queryMode == "advanced") {
				request.onreadystatechange = function() {
    				if (request.readyState == 4) {
    					if (query.cancel) return false;
    					var i, data, handle, result, results;
    					results = Array();
    					eval("data = " + request.responseText);
    					if (data) {
    						for (i = 0; i < data.results.length; i++) {
    							result = data.results[i];
    							handle = query.data[result.id];
    							if (handle) {
    								if (handle.readyState == 1) {
    									handle.readyState = 2;
    									handle.hits = result.hits;
    									results[results.length] = handle;
    								}
    							}
    						}
    						onQueryData(results);
							for (i = 0; i < query.data.length; i++) {
								if (query.data[i].readyState != 2) {
									i = 99999;
								}
							}
							if (i < 99999) onQueryExecuted();
    					}
    				}
    			}
			}
			request.open("GET", buffer, true);
			request.send(null);
			setTimeout(function(){query.sendCluster();}, postInterval);
		}
		if (c < clusterSize) {
			this.processing = false;
			// onQueryExecuted();
		}
	}
	
	this.cancelSplit = function() {
		this.cancel = true;
		this.processing = false;
		onQueryCanceled();
	}
	
	this.processingTime = function() {
		return (new Date()).getTime() - startTime;
	}
	
	this.setTime = function() {
		startTime = (new Date()).getTime();
	}
}

function appendBasicQuery(id, hits) {
    var handle = query.data[id];
    if (handle) {
    	if (handle.readyState < 2) {
    		handle.readyState = 2;
    		handle.hits = hits;
    		handle.pop = (handle.tld.hits == 0) ? 0 : handle.hits / handle.tld.hits * 10000;
    		return handle;
    	}
		else {
			return false;
		}
    }
	else {
		return false;
	}
}

function appendMultiQuery(id, hits) {
    var handle = query.data[id];
    if (handle) {
    	if (handle.readyState < 2) {
    		handle.readyState = 2;
    		handle.hits = hits;
    		return handle;
    	}
		else {
			return false;
		}
    }
	else {
		return false;
	}
}

function appendAdvancedQuery(id, hits) {
    var handle = query.data[id];
    if (handle) {
    	if (handle.readyState < 2) {
    		handle.readyState = 2;
    		handle.hits = hits;
    		return handle;
    	}
		else {
			return false;
		}
    }
	else {
		return false;
	}
}