/*
    Copyright (C) 2008  Ivo Toby, Internet Voor Ondernemers, http://www.i-v-o.nl / http://syntacticsugar.nl 

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

	Crudder Version : 0.50b
 */


	var crudderTable = Class.create(crudderView, {
		
		initialize:function($super, metaData, container, controller){
			$super(metaData, container, controller);
			this.instID = 'crudderTable.' + parseInt(Math.random()*1000000);
		},

		drawGrid : function(){
			var table = new Element('table', {className:'crudderGrid'});
			this.container.update(table);
			var head = this.drawHead(table);
			this.dataContainer = table;
			//get data with the factory
			this.getData();
		},
		
		drawHead : function(container){
			// create title of table:
			var td = new Element('td', {colspan:this.getColCount() }).update(this.metaData.table.friendlyName);
			var tr = new Element('tr').update(td);
			var tbody = new Element('tbody', {className:'crudderGridTitle'}).update(tr);
			container.insert(tbody);
			
			if (this.metaData.config.alphaIndex){
				var td = new Element('td', {colspan:this.getColCount(), id:this.instID + '_alphaIndex' });
				
				var tr = new Element('tr').update(td);
				var tbody = new Element('tbody').update(tr);
				container.insert(tbody);
				
				this.createAlphaIndex(td);
			}
			
			// create a navigator:
			var td = new Element('td', {colspan:this.getColCount(), id:this.instID + '_northNavigator' });
			var tr = new Element('tr').update(td);
			var tbody = new Element('tbody').update(tr);
			container.insert(tbody);

			var tr = new Element('tr');
			var tbody = new Element('tbody', {className:'crudderGridHead'}).update(tr);
			container.insert(tbody);
			if (this.metaData.config.showIndex){
				tr.insert(new Element('td'));// head of index column
			}
			this.metaData.config.gridfields.each(
				(function(gridField){
					gridField = this.fields.get(gridField);
					gridField.drawGridHead(tr);
				}).bind(this)
			)
			tr.insert(new Element('td'));// head of delete column
			tr.insert(new Element('td'));// head of edit column
			
			if (!this.metaData.config.disableAdd){
				var addTD = new Element('td');
				var button = new Element('button', {id:this.instID+"_addButton", className:'crudderAddRecordButton'}).update(this.controller.lang.get('addRecordButton'))
				addTD.insert(button);
				tr.insert(addTD);// head of add-button
				button.observe('click', this.addRecord.bind(this))
			}else{
				var addTD = new Element('td');
				tr.insert(addTD);
			}
		},
		
		createAlphaIndex : function(container){
			var alphaContainer = new Element('div', {className:'alphaIndex'});
			container.insert(alphaContainer);
			['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q', 'r','s','t','u','v','w','x','y','z'].each(
				(function(letter){
					var spannertje = new Element('span').update(letter);
					spannertje.letter = letter;
					if (letter != 'z') spannertje.insert(' | ');
					alphaContainer.insert(spannertje);
					spannertje.observe('click', this.filterFromAlphaIndex.bindAsEventListener(this))
				}).bind(this)
			)
			this.alphaContainer = alphaContainer;
		},
		
		filterFromAlphaIndex : function(event){
			var letter = event.element().letter;
			this.page = 0;
			this.controller.factory.set('page', this.page);
			this.controller.factory.set('alphaFilterOn', this.metaData.config.alphaIndex);
			this.controller.factory.set('alphaFilter', letter);
			this.drawGrid();// DO NOT CALL getData, everything needs to be updated.
		},
		
		drawGridData : function(req){
			var existingRows = $$('.crudderDataRow');
			if (existingRows.length >0){
				existingRows.each(
					function (elem){$(elem).remove()}
				)
			}
			var i = 0;
			var data = req.responseJSON.data;
			this.rowCount = req.responseJSON.table.rowCount;
			$A(data).each(
				(function(row){
					var tr = new Element('tr');
					var tBody = new Element('tbody', {className:'crudderDataRow', id:row[this.pKey]+"_row"}).update(tr);
					this.dataContainer.appendChild(tBody);
					if (i%2==0) {
						tBody.addClassName('on');
					}
					this.drawGridDataRow(row, tr, i);
					this.drawRowControls(row, tr);
					i++;
				}).bind(this)
			)
			this.drawNavigator($(this.instID + '_northNavigator'));
			this.controller.handleCustomEvent('afteropen');
		},
		
		drawGridDataRow : function(row, container, idx){
			if (this.metaData.config.showIndex){
				var td = new Element('td', {className:'crudderDataCell', id:row[this.pKey] + "_index_"}).update(this.getRealIndex(idx));
				container.insert(td);
			}
			this.metaData.config.gridfields.each(
				(function(gridField){
					if (this.metaData['refdata_' + gridField]){
						var gridValue = row[gridField];
						if (gridValue){
							var gridValueArray = this.metaData['refdata_' + gridField].findAll(
								(function(token){
									if (token.pk == gridValue) return token;
								}).bind(this)
							)
							if (gridValueArray.length>0){
								gridValue = gridValueArray[0].value; 
							}
						}
					}else{
						var gridValue = row[gridField];
					}
					//gridValue = stripslashes(gridValue);
					var td = new Element('td', {className:'crudderDataCell', id:row[this.pKey] + "_" + gridField}).update(gridValue);
					container.insert(td);
				}).bind(this)
			)
			
		},
		
		drawRowControls : function(row, container){
			// controls are: delete/edit, that's it:)
			//this.controller.lang.delIcon
			if (!this.metaData.config.disableDelete){
				var delIcon = new Element('img', {src:this.controller.imgPath + 'delIcon.gif', alt:this.controller.lang.get('delIconAlt')});
				delIcon.data = row;
				container.insert(new Element('td', {className:'crudderControls'}).update(delIcon));
				delIcon.observe('click', this.removeRecord.bindAsEventListener(this));
			}else{
				container.insert(new Element('td', {className:'crudderControls'}));
			}
			var delIcon = new Element('img', {src:this.controller.imgPath + 'edit.gif', alt:this.controller.lang.get('editIconAlt')});
			delIcon.data = row;
			container.insert(new Element('td', {className:'crudderControls'}).update(delIcon));
			delIcon.observe('click', this.editRecord.bindAsEventListener(this));
			
			container.insert(new Element('td').update('')); //spare column
		},
		
		drawNavigator : function(container){
			var navigator = new crudderNavigator(this.rowCount, this.page, this.itemsPerPage, this.metaData.config.maxShownPages);
			navigator.controller = this.controller;
			navigator.callBack = this.setPage.bind(this);
			navigator.callBackItemsPerPage = this.setItemsPerPage.bind(this);
			navigator.searchCallBack = this.search.bind(this);
			navigator.resetCallBack = this.resetSearch.bind(this);
			if (this.metaData.config['export']){
				navigator.exportCallBack = this.exportView.bind(this);
			}
			navigator = navigator.drawNavigator(container);
		},
		
		exportView : function(event){
//			var elem = event.element();
//			var container = elem.parentNode;
//			this.controller.factory.exportData();
			
		},
		
		resetSearch : function(){
			this.controller.factory.unset('filter');
			this.drawGrid();
		},
		
		search : function(searchFor){
			this.page = 0;
			this.controller.factory.set('page', this.page);
			this.controller.factory.set('filter', searchFor);
			this.drawGrid();// DO NOT CALL getData, everything needs to be updated.
			if (searchFor) {
				this.alphaContainer.hide();
			}else{
				this.alphaContainer.show();
			}
		},
		
		getData : function(){
			this.controller.factory.execute(this.drawGridData.bind(this));
		},
		
		getRealIndex : function(fakeIdx){
			var pageIdxAtStart = (this.page * this.itemsPerPage);
			return (pageIdxAtStart + fakeIdx + 1);
		},
		
		getColCount : function(){
			if (this.metaData.config.showIndex) return this.metaData.config.gridfields.length + 4;
			return this.metaData.config.gridfields.length + 3;
		},
		
		setItemsPerPage : function(amount){
			this.controller.factory.set('itemsPerPage', amount);
			this.itemsPerPage = amount;
			this.setPage(0);
//			this.getData();
		},
		
		setPage : function(pageNum){
			this.controller.factory.set('page', pageNum);
			this.page = pageNum;
			this.getData();
		},
		
		editRecord: function(event){
			this.controller.editRecord(event.element().data);
		},
		
		addRecord : function(){
			this.controller.addRecord();
		},
		
		removeRecord : function(event){
			if (confirm(this.controller.lang.get("deleteAreYouSure"))){
				this.controller.handleCustomEvent('beforedelete');
				var pk = event.element().data[this.pKey];
				if (pk){
					var RPCObj = new crudderRPC(this.controller.config, this.controller.rpcPath);
//					RPCObj.debug = true;
					RPCObj.createCall();
					RPCObj.attachWaiter(this.controller.waiter, this.controller);
					RPCObj.attachUnWaiter(this.controller.unWaiter, this.controller);
					RPCObj.setCallback(this.setRemoved.bind(this));
					RPCObj.setMethod('delete');
					RPCObj.addArgument('pKey', pk);
					RPCObj.call();
				}
			}
		},
		
		setRemoved : function(req){
			if (req.responseJSON[0].message=='true'){
				this.controller.handleCustomEvent('afterdelete');
				this.getData();
			}else{
				alert(this.controller.lang.get("removeError"));
			}
		},
		
		sort: function(fieldObj){
			this.controller.factory.set('order', fieldObj.field.name);
			this.controller.factory.set('orderBy', fieldObj.sorted);
			this.getData();
			this.metaData.config.gridfields.each(
				(function(gridField){
					if (gridField != fieldObj.field.name) this.fields.get(gridField).reset();
				}).bind(this)
			)
		}
		
	})