var sw3_trace = false;

(function() {
	var loader = new YAHOO.util.YUILoader({
		base: '/common/yui/build/',
		require: ["connection","autocomplete","datatable","paginator"],
		loadOptional: false,
		combine: false,
		filter: "min",
		allowRollup: true,
		onSuccess: function() {
			YAHOO.util.Event.onDOMReady(initDataTable);
		}
	});

// Load the files using the insert() method.
	loader.insert();
})();

function initDataTable() {

if (sw3_trace) console.log("initDataTable()");

	this.formatDate = function(elCell, oRecord, oColumn, oData) {
		elCell.innerHTML = YAHOO.util.Date.format(oData, {format:"DD/MM/YYYY"});
	}
	
	this.formatUrl = function(el, oRecord, oColumn, oData) {
        if (YAHOO.lang.isString(oData) && oData != '') {
			var s = '<img src="/common/images/pixel.gif">';
			if (oData.indexOf('@') != -1) {
				el.innerHTML = '<a href="mailto:' + oData + '" class="db_mail" target="_blank">' + s + '</a>';
			} else {
				if (oData.substr(0, 7) == 'http://') oData = oData.substr(7);
				el.innerHTML = '<a href="http://' + oData + '" class="db_link" target="_blank">' + s + '</a>';
			}
        }
        else {
			el.innerHTML = YAHOO.lang.isValue(oData) ? oData : '';
        }
	}
	
	YAHOO.widget.DataTable.formatCurrency = function(el, oRecord, oColumn, oData) {
		el.innerHTML = YAHOO.util.Number.format(oData, {
				suffix:"€",
				decimalPlaces:2,
				decimalSeparator:",",
				thousandsSeparator:" "
			});
	}
	
	var re_datetime = /(\d{1,2})\/(\d{1,2})\/(\d{4})(\s+(\d{1,2})(:(\d{1,2}))?(:(\d{1,2}))?)?(\s+GMT)?/;
	YAHOO.util.DataSource.parseDate = function(oData) {
		if (oData instanceof Date) {
			return oData;
		} else {
			var date;
			s = new String(oData);
			var d = s.match(re_datetime);
			if (d) {
				date = new Date(d[3], 0, 1);
				var offset = 0;
				date.setMonth(d[2] - 1); // assume d/m/y for now
				date.setDate(d[1]);
				if (d[5]) { date.setHours(d[5]); }
				if (d[7]) { date.setMinutes(d[7]); }
				if (d[9]) { date.setSeconds(d[9]); }
				if (d[10]) { offset = date.getTimezoneOffset() * 60 * 1000; }
				date.setTime(date.getTime() - offset);
			}
		}
		
		// Validate
		if (date instanceof Date) {
			return date;
		}
		else {
			return null;
		}
	}
	
	var json_flds = [];
	this.myColumnDefs = [];
	var filters = [];
	var xSelect = '';
	var xSearch = '';
	var first_list = true; // dyn
	for (var i=0; i<sw3.db.format.length; i++) {
		var d = sw3.db.format[i];
		var fld_key = 'c'+i;
		var json_fld = {key:fld_key};
		var cd = {key:fld_key, label:d.name, className:'db_' + d.type};
		switch (d.type) {
		case 'url':
			cd.formatter = this.formatUrl;
			break;
		case 'date':
			json_fld.parser = YAHOO.util.DataSource.parseDate;
			cd.formatter = this.formatDate;
			break;
		case 'num':
			json_fld.parser = YAHOO.util.DataSource.parseNumber;
			cd.formatter = YAHOO.widget.DataTable.formatNumber;
			break;
		}
		if (d.sortable) cd.sortable = true;
		if (d.resizeable) cd.resizeable = true;
		if (d.searchable) {
			var dynamic = false;
			switch (d.searchable) {
			case 'text':
				var id = 'db_search_' + i;
				xSearch += '<div><label for="' + id + '">' + sw3.htmlEncode(d.name) + '</label><input type="text" name="' + id + '" id="' + id + '" /><img src="/common/images/pixel.gif"></div>';
				break;
			case 'ac':
				var id = 'db_search_' + i;
				xSearch += '<div id="db_ac_' + i + '"><label for="' + id + '">' + sw3.htmlEncode(d.name) + '</label><input id="' + id + '" type="text"><div id="db_cont_' + i + '"></div></div>'
				break;
			case 'select':
				var id = 'db_select_' + i;
				xSelect += '<div><label for="' + id + '">' + sw3.htmlEncode(d.name) + '</label><select name="' + id + '" id="' + id + '"></select></div>';
				dynamic = !first_list;
				first_list = false;
				break;
			}
			filters.push({
					index: i,
					'id': id,
					key: fld_key,
					type: d.searchable,
					dynamic: dynamic,
					value: '',
					v: []
				});
		}
		json_flds.push(json_fld);
		if (!d.hide) this.myColumnDefs.push(cd);
	}
	this.filters = [];
	for (var i=0; i<filters.length; i++) {
		if (filters[i].type == 'select') this.filters.push(filters[i]);
	}
	for (var i=0; i<filters.length; i++) {
		if (filters[i].type != 'select') this.filters.push(filters[i]);
	}
	var elSearch = document.getElementById('dbSearch');
	if (elSearch) {
		elSearch.innerHTML = xSearch;
	}
	var elSelect = document.getElementById('dbSelect');
	if (elSelect) {
		elSelect.innerHTML = xSelect;
	}

if (sw3_trace) console.log("DataSource");
//	this.json_DataSource = new YAHOO.util.DataSource('/files/db/' + sw3.db.id + '.json', {responseType: YAHOO.util.DataSource.TYPE_JSON});
	this.json_DataSource = new YAHOO.util.XHRDataSource('/files/db/' + sw3.db.id + '.json'); //, {responseType: YAHOO.util.DataSource.TYPE_JSON});
	this.json_DataSource.responseType = YAHOO.util.XHRDataSource.TYPE_JSON;
	
if (sw3_trace) console.log("responseSchema");
	this.json_DataSource.responseSchema = {
		resultsList: 'data',
		fields: json_flds
	};
	
	this.re_protect = /([\]\[\\.$()^?*+-])/g;
	this.re_blanks = /\s+/g;
	this.fn_DS_provider = function(oRequest) {
		var new_results = [];
		var flt = [];
		var dyn = [];
		var search_nbr = 0;
		for (var i = 0; i<this.filters.length; i++) {
			var v = this.filters[i].value;
			var filter = {
					key: this.filters[i].key,
					re: false,
					flt: this.filters[i], // dyn
					id: this.filters[i].id, // dyn
					opt: v,
					v: false // dyn
				};
			if (v != '') {
				search_nbr++;
				v = v.replace(this.re_protect, '\\$1');
				switch (this.filters[i].type) {
				case 'text':
					v = v.replace(this.re_blanks, '.*'); //'\\s+'
					break;
				case 'ac':
					v = '^' + v;
					break;
				case 'select':
					v = '^' + v + '$';
					break;
				}
				filter.re = new RegExp(v, 'i');
			}
			if (this.filters[i].dynamic) { // dyn
				filter.v = new Object();
			}
			if (filter.re || filter.v) flt.push(filter);
		}
		
        var oPaginator = this.custDataTable ? this.custDataTable.get('paginator') : null;
		if (search_nbr > 0) {
			for (var i=0; i<this.json_results.length; i++) {
				var rec = this.json_results[i];
				var ok = true;
				for (var j = 0; j<flt.length; j++) {
					var f = flt[j];
					var data = rec[f.key];
					if (ok && f.v && data != '') f.v[data] = true; // dyn
					if (f.re) {
						ok = ok && data.toLowerCase().match(f.re);
						if (!ok) break;
					}
				}
				if (ok) {
					new_results.push(rec);
				}
			}

			for (var i = 0; i<flt.length; i++) { // dyn
				var f = flt[i];
				if (f.v) {
					var el = document.getElementById(f.id);
					el.options.length = 0;
					el.options[0] = new Option('');
					var v = [];
					for (x in f.v) {
						v.push(x);
					}
					v.sort();
					var prev_value = '';
					for (var j = 0; j<v.length; j++) {
						if (v[j].toLowerCase() != prev_value.toLowerCase()) {
							el.options[el.options.length] = new Option(v[j], v[j]);
							if (f.opt.toLowerCase() == v[j].toLowerCase()) el.selectedIndex = el.options.length-1;
							prev_value = v[j];
						}
					}
					if (el.options.length == 2) el.selectedIndex = 1;
				}
			}

			if (oPaginator) oPaginator.setTotalRecords(flt.length, false);
			return new_results;
		} else {
			for (var i = 0; i<flt.length; i++) { // dyn
				var f = flt[i];
				if (f.v) {
					var el = document.getElementById(f.id);
					el.options.length = 0;
					el.options[0] = new Option('');
					var v = f.flt.v;
					for (var j = 0; j<v.length; j++) {
						el.options[el.options.length] = new Option(v[j], v[j]);
					}
				}
			}

			if (oPaginator) oPaginator.setTotalRecords(this.json_results.length, false);
			return this.json_results;
		}
	}

	var self = this;
	this.fn_DataSource = new YAHOO.util.DataSource(
		function (oRequest) { return self.fn_DS_provider(oRequest); }, // wrap function to preserve scope
		{responseType: YAHOO.util.DataSource.TYPE_JSARRAY}
	);
	this.fn_DataSource.responseSchema = {
		fields: json_flds
	};
	
	this.onjsonDataReturnSetRows = function(oRequest, oResponse, oPayload) {
		this.json_results = oResponse.results;

		var fselect = [];
		var fac = [];
		for (var i = 0; i<this.filters.length; i++) {
			var f = this.filters[i];
			switch (f.type) {
			case 'select':
				fselect.push({
					key: this.filters[i].key,
					idx: i,
					v: new Object()
				});
				break;
			case 'ac':
				fac.push({
					key: this.filters[i].key,
					idx: i,
					ds: new Array()
				});
				break;
			}
		}
		if (fselect.length > 0) {
			for (var i=0; i<this.json_results.length; i++) {
				var rec = this.json_results[i];
				for (var j = 0; j<fselect.length; j++) {
					var val = rec[fselect[j].key];
					if (val != '') fselect[j].v[val] = true;
				}
				for (var j = 0; j<fac.length; j++) {
					var f = fac[j];
					var val = rec[f.key];
					if (val != '') f.ds.push(val);
				}
			}
			for (var i = 0; i<fselect.length; i++) {
				var el = document.getElementById(this.filters[fselect[i].idx].id);
				el.options.length = 0;
				el.options[0] = new Option('');
				var v = [];
				for (x in fselect[i].v) {
					v.push(x);
				}
				v.sort();
				var prev_value = '';
				for (var j = 0; j<v.length; j++) {
					if (v[j].toLowerCase() != prev_value) {
						this.filters[fselect[i].idx].v.push(v[j]); // dyn
						el.options[el.options.length] = new Option(v[j], v[j]);
						prev_value = v[j].toLowerCase();
					}
				}
			}
			for (var i = 0; i<fac.length; i++) {
				var f = this.filters[fac[i].idx];
				f.ds = fac[i].ds;
				var myDataSource = new YAHOO.widget.DS_JSArray(f.ds);
//				myDataSource.queryMatchContains = true;
				var myAutoComp = new YAHOO.widget.AutoComplete(f.id, 'db_ac_' + f.index, myDataSource);
				myAutoComp.itemSelectEvent.subscribe(function(){
					self.fnFilter();
				});
			}
		}

		var oConfigs = {
			initialRequest: '',
			paginator: new YAHOO.widget.Paginator({
				rowsPerPage: sw3.db.rowsPerPage,
				alwaysVisible: false,
				firstPageLinkLabel: '&lt;&lt;&nbsp;' + sw3lang['lib_db_first'],
				lastPageLinkLabel: sw3lang['lib_db_last'] + '&nbsp;&gt;&gt;',
				previousPageLinkLabel: '&lt;&nbsp;' + sw3lang['lib_db_prev'],
				nextPageLinkLabel: sw3lang['lib_db_next'] + '&nbsp;&gt;'
				
			})
		};

		this.custDataTable = new YAHOO.widget.DataTable('dbContainer', this.myColumnDefs, this.fn_DataSource, oConfigs);
	}
	
	this.onjsonDataReturnError = function(oRequest, oResponse, oPayload) {
		alert(sw3lang['lib_db_badfile']);
		console.log(oRequest);
		console.log(oResponse);
		console.log(oPayload);
	}
	
    var oCallback = {
        success : this.onjsonDataReturnSetRows,
        failure : this.onjsonDataReturnError,
        scope   : this,
        argument: {}
    };
	this.json_DataSource.sendRequest('', oCallback);

	this.fnFilter = function(e, idx) {
		if (YAHOO.lang.isUndefined(idx)) {
			idx = self.textField; // coming from timer
		}
		if (self.timer) {
			clearTimeout(self.timer);
			self.timer = false;
		}
		var has_changed = false;
		for (var i = 0; i<self.filters.length; i++) {
			var previous_value = self.filters[i].value;
			self.filters[i].value = YAHOO.util.Dom.get(self.filters[i].id).value;
			if (i > idx && self.filters[i].dynamic) {
				self.filters[i].value = ''; // erase, because parent filter changed
			}
			has_changed |= (previous_value != self.filters[i].value);
		}
		if (has_changed) {
			self.fn_DataSource.sendRequest('',
				{
					success : self.custDataTable.onDataReturnInitializeTable,
					failure : self.custDataTable.onDataReturnInitializeTable,
					scope   : self.custDataTable,
					argument: {}
				}
			);
		}
	}
	this.timer = false;
	this.fnTimer = function(e, idx) {
		if (self.timer) {
			clearTimeout(self.timer);
		}
		self.textField = idx;
		if (e.keyCode == 13) {
			fnFilter();
		} else {
			self.timer = setTimeout("fnFilter()", 2000);
		}
	}
	for (var i = 0; i<this.filters.length; i++) {
		var f = this.filters[i];
		YAHOO.util.Event.addListener(f.id, "change", this.fnFilter, i);
		switch (f.type) {
		case 'select':
			break;
		case 'text':
			YAHOO.util.Event.addListener(f.id, "keypress", this.fnTimer, i);
			YAHOO.util.Event.addListener(f.id, "keydown", this.fnTimer, i);
			break;
		}
	}
}
