if (!window.ExtendedDataTable) window.ExtendedDataTable = {};

ExtendedDataTable.DataTable = Class.create({
	initialize : function(id, options) {
		this.id = id;
		this.groups = [];
		
		// register event handlers
		this.options = options;
		this.selectionManager = new ExtendedDataTable.SelectionManager(options, this);
		
		if (this.options.sortFunction) {
			this.sortFct = this.options.sortFunction;
			this.eventCellClicked = this.OnCellMouseClicked.bindAsEventListener(this);
		}
		this.onGroupToggleFct = this.options.onGroupToggleFunction;
		if (this.options.onColumnResize != null){
			this.onColumnResize = this.options.onColumnResize;
			this.columnWidths = "";
		}		
		this.eventContainerResize = this.OnWindowResize.bindAsEventListener(this);
		this.eventGroupRowClicked = this.OnGroupRowMouseClicked.bindAsEventListener(this);
		Event.observe(window, "resize", this.eventContainerResize);
		this.minColumnWidth = this.options.minColumnWidth;
		
		var grid = this;

		Utils.execOnLoad(
			function(){
				grid.update(true);
			},
			Utils.Condition.ElementPresent(id+':header'), 5);
	},
	
	_findParentElement: function(event, element) {
		var el = null;
		if(ClientUILib.isSafari) {
			var targetCell = event.currentTarget;
			if(targetCell && targetCell.tagName.toLowerCase() == element) {
				el = targetCell;
			} else {
				var e = (event.target || event.srcElement);
				while((e != null) && (e.tagName.toLowerCase() != element) && (e != document)){
					e = e.parentNode;
				}//while
				if ((e) && (e.tagName.toLowerCase() == element)){
					el = e;
				}
			}
		} else {
			el = Event.findElement(event, element);
		}
		return el;
	},
	
	OnCellMouseClicked: function(event) {
		//get column id
		var el = this._findParentElement(event, "th");
		var columnId = (el) ? el.id : null;
			
		if (columnId && (columnId != "")){
			this.showSplashScreen();
			this.sortFct(event, columnId);		
		}
		Event.stop(event);	
	},
	
	preSendAjaxRequest: function(){
		//remove listeners
		Event.stopObserving(window, 'resize', this.eventContainerResize);
		Event.stopObserving(document, 'mousemove', this.header.eventSepMouseMove);
		Event.stopObserving(document, 'mouseup', this.header.eventSepMouseUp);
		//show splash screen
		this.showSplashScreen();
	},
		
	showSplashScreen: function(){
        if (ClientUILib.isOpera) {
            this.mainDiv.setStyle({display:'none'});
        }
        this.table.setStyle({visibility:'hidden'});
        this.mainDiv.getElement().removeClassName('extdt-splscr-hddn');
        this.mainDiv.getElement().addClassName('extdt-splscr-vsbl');
	},
	
	hideSplashScreen: function(){
        if (ClientUILib.isOpera) {
            this.mainDiv.setStyle({display:''});
        }
		this.table.setStyle({visibility:'visible'});
		this.mainDiv.getElement().removeClassName('extdt-splscr-vsbl');
		this.mainDiv.getElement().addClassName('extdt-splscr-hddn');		
	},	
	
	OnWindowResize: function(event) {
		this.updateLayout();
	},
	getColumnsNumber: function() {
		return this.columnsNumber;
	},
	getColWidth: function(columnNumber) {
		
	},
	getColumns: function() {
		return this.cols;
	},
	OnGroupRowMouseClicked: function(event) {
		
		var groupRow = this._findParentElement(event, "tr");
		var bExpanded = !(groupRow.getAttribute('expanded') == 'true');
		var sExpanded = bExpanded ? 'true' : 'false';
		var groupIndex = parseInt(groupRow.getAttribute('groupindex'));
		if (this.onGroupToggleFct){
			this.onGroupToggleFct(event, groupIndex);
		}
		groupRow.setAttribute('expanded', sExpanded);
		var imageDiv = groupRow.firstChild.firstChild.firstChild;
		this.toggleImageSource(imageDiv);
		this.setGroupExpanded(groupIndex, bExpanded);
		Event.stop(event);
	},
	
	toggleImageSource: function(imageDiv) {
		var src = imageDiv.getAttribute('src');
		var alternateSrc = imageDiv.getAttribute('alternatesrc');
		imageDiv.setAttribute('src', alternateSrc);
		imageDiv.setAttribute('alternatesrc', src);		
	},
	
	getColumnWidth: function(columnNumber) {
        if ((columnNumber < this.getColumnsNumber()) && (columnNumber >=0)) {
            var col = this.getColumns()[columnNumber+this.getColumnsNumber()];
            if (col.offsetWidth) {
                return col.offsetWidth;
            }else{
                //cols don't have offsetWidth in Opera
                return parseInt(col.width);
            }
        }else{
            return null;
        }
	},
	
	setGroupExpanded: function(iGroupIndex, bValue) {
		var group = this.groups[iGroupIndex];
		
		var sVisibility;
		var sBorder;
		var sEmptyCells;
		
		if (bValue) {
			sVisibility = '';
			sBorderColor = '';
		}else{
			sVisibility = 'none';
			sBorderColor = 'transparent';
		}
		var size = group.size();
		for (var i=0; i<size; i++) {
			group[i].style.display = sVisibility;
			if (ClientUILib.isIE7){
				//prevent IE from showing borders of cells
				//which parents have been hidden :|
				var cells = group[i].childNodes;
				for (var j=0; j<cells.length; j++) {
					cells[j].style.borderColor = sBorderColor;
				}
			}
		}
	},
	
	createControls: function() {
		var id = this.id;
		this.table = new ClientUI.common.box.Box(this.id +":tu",null,true);
		this.mainDiv = new ClientUI.common.box.Box(this.id,null,true);
		this.outerDiv = new ClientUI.common.box.Box(this.id +":od",null,true);
		this.tableB = new ClientUI.common.box.Box(this.id +":n",null,true);
		this.fakeIeRow = $(this.id +":fakeIeRow");
		this.fakeIeBodyRow = $(this.id +":body:fakeIeRow");
		this.header = new ExtendedDataTable.DataTable.header(this.id +":header",this);
		this.header.minColumnWidth = this.minColumnWidth;
		this.cols = this.table.getElement().getElementsByTagName("col");
		this.columnsNumber = this.cols.length/2;
		this.scrollingDiv = new ClientUI.common.box.Box(this.id +":sd",null,true);
		this.groupRows = [];
		
		if (ClientUILib.isOpera) {
			//no overflow-x nor overflow-y in Opera
			this.scrollingDiv.setStyle({overflow: 'scroll',
				width: this.mainDiv.getWidth()
			});
			this.table.setStyle({width: this.mainDiv.getWidth()});
		};
		
		var i = 0;
		var groupRow = $(id+':group-row:'+i);
		while (groupRow != null) {
			this.groupRows[i] = groupRow;
			Utils.DOM.Event.removeListeners(groupRow);
			Utils.DOM.Event.observe(groupRow,'click',this.eventGroupRowClicked);
			i++;
			groupRow = $(id+':group-row:'+i);
		}
	},
	getScrollbarWidth: function() {
		var sd = this.scrollingDiv.getElement();
		return sd.offsetWidth - sd.clientWidth;
	},
	validateColumnsWidth: function(columns,excessWidth) {
		var i=1;
		var endIndex = columns.length/2-1;
		while ((i < endIndex) && (excessWidth > 0)) {
			var col = columns[columns.length-i-1];
			var spareWidth = col.offsetWidth - this.minColumnWidth;
			if (spareWidth > excessWidth) {
				col.width = col.offsetWidth - excessWidth;
				columns[endIndex - i].width = col.width;
				excessWidth = 0;
			}else{
				col.width = col.offsetWidth - spareWidth;
				columns[endIndex - i].width = col.width;
				excessWidth -= spareWidth;
			}
			i++;
		}
	},	
	updateLayout: function() {
		var table = this.table.getElement();
		this.grid = table;
		var outerDiv = this.outerDiv.getElement();
		var cols = this.getColumns();
		var header = this.header;
		var scrollingDiv = this.scrollingDiv;
		var mainDivHeight = this.mainDiv.getHeight();
		var mainDivWidth = this.mainDiv.getWidth();
		var headerChildren = header.getColumnCells();
		
		var footers = table.getElementsByTagName('tfoot');
		var footerHeight = 0;
		if (footers.length > 0) {
			footerHeight = footers[0].offsetHeight;
		}
		var columnsNumber = this.getColumnsNumber();		

		var visibleHeaderWidth = this.header.getVisibleWidth();
		var excessWidth = this.header.getVisibleWidth() - this.mainDiv.getWidth();
		if (excessWidth > 0) {
			var scrollbarExcess = scrollingDiv.getElement().offsetWidth - scrollingDiv.getElement().clientWidth;
			excessWidth += scrollbarExcess;
			this.validateColumnsWidth(cols,excessWidth);
		}else{			
			var excessWidth = visibleHeaderWidth - scrollingDiv.getElement().clientWidth;
			if (excessWidth>0) {
				this.validateColumnsWidth(cols,excessWidth);
			}
		}
		if (ClientUILib.isOpera) {
            var _stl = headerChildren[0].getStyles().borderRightWidth;
            _stl = parseInt(_stl.replace(/"px"/,""))*2;
			var newWidth = mainDivWidth - visibleHeaderWidth - (this.header.getColumnsNumber()-1)*_stl;
			cols[columnsNumber-1].width = newWidth;
			ClientUILib.log(ClientUILogger.INFO, "_stl: " + _stl);
			ClientUILib.log(ClientUILogger.INFO, "newWidth: " + newWidth);
			newWidth -= this.getScrollbarWidth()-1; 
			if (newWidth <= 0) {
                newWidth = 1;
			}		
			cols[cols.length-1].width = newWidth;
			ClientUILib.log(ClientUILogger.EVENT, "newWidth: " + newWidth);
            var cols = this.header.getColumns();
            var columnsNumber = this.header.getColumnsNumber();
            for (var i=0; i<columnsNumber-1; i++) {
                cols[i].width = parseInt(cols[i+columnsNumber].width) - _stl;
            }
		}else{
			cols[columnsNumber-1].width = null;
			cols[cols.length-1].width = null;
		}
		var newHeight = mainDivHeight - header.getHeight() - footerHeight - 2;
		var captions = this.table.getElement().getElementsByTagName('caption');
		if (captions.length > 0) {
            newHeight -= captions[0].offsetHeight;
		}
		ClientUILib.log(ClientUILogger.INFO, "footerHeight: " + footerHeight);
		scrollingDiv.setStyle('height:'+ newHeight +'px;');
		for (var i=0; i<headerChildren.length-1; i++) {
			var headerChild = headerChildren[i];
			var isSortable = headerChild.getAttribute('sortable');
			if ((isSortable) && (isSortable.indexOf('true') == 0)) {
				Utils.DOM.Event.removeListeners(headerChild);
				Utils.DOM.Event.observe(headerChild, 'click',  this.eventCellClicked);
			}
		};
		header.adjustSeparators();
		this.hideSplashScreen();
	},
	update: function(refreshEvents) {
		this.createControls();
		if ( !ClientUILib.isIE7 ) {
			if (this.fakeIeRow) {
				this.table.getElement().deleteRow(this.fakeIeRow);	
				this.fakeIeRow = null;
			}
			if (this.fakeIeBodyRow) {
				this.tableB.getElement().deleteRow(this.fakeIeBodyRow);
				this.fakeIeBodyRow = null;
			}
		}		
		this.selectionManager.refreshEvents();
		this.updateLayout();
		this.selectionManager.restoreState();
	}

});