//************** The AQUA Project (AJAX Quick Utilities for Applications)
//************** Author: QuartZoft (http://quartzoft.com)
//*************************************************************************

//************** Collection 
//************************************************************************

function Collection(){
	this.index = 0;
	this.currentIndex = 0;
	this.items = new Array();
	this.add = function(item){
		var _index = this.index;
		this.items[_index] = item;
		this.index++;	
		return _index;
	}
	this.set = function(item,_index){
		this.items[_index] = item;
	}
	this.get = function(_index){
		return this.items[_index];
	}
	this.size = function(){
		return this.items.length;
	}
	this.remove = function(index){
		this.items.splice(index, 1);
		this.index--;
	}
	this.clear = function(){
		this.items = new Array();
		this.index = 0;
		this.currentIndex = 0;
	}
	this.nextIndex = function(){
		if(this.currentIndex == this.index){
			this.currentIndex = 0;
			return null;
		}else{
			var _item = this.items[this.currentIndex];
			this.currentIndex++;
			if(_item){
				return this.currentIndex - 1; 
			}
			return this.nextIndex();
		}
	}
}

//************** StringBuilder 
//*************************************************************************

function StringBuilder(value){
    this.items = new Array("");
	this.append  = function (value){
		if (value){
			this.items.push(value);
		}
	}
	this.clear = function (){
		this.items.length = 1;
	}
	this.toString = function (){
		return this.items.join("");
	}
	this.append(value);
}


//************** CSS Styling 
//*************************************************************************

function Style(){
	this.items = new Collection();
	this.styleString = null;
	this.getItem = function(rule){
		var index = this.items.nextIndex();
		while(index!=null){
			if(this.items.get(index).rule == rule){
				return this.items.get(index).value;
			}
			index = this.items.nextIndex();
		}
		return '';
	}
	this.setItem = function(rule, value){
		var index = this.items.nextIndex();
		while(index!=null){
			if(this.items.get(index).rule == rule){
				this.items.set(new StyleItem(rule,value),index);
				this.items.currentIndex = 0;
				return;
			}
			index = this.items.nextIndex();
		}
		this.items.add(new StyleItem(rule,value));	
	}
	this.setStyleString = function(_value){
		this.styleString = _value;	
	}
	this.toString = function(){
		var str = '';
		if(this.styleString != null){
			str = styleString;
			if(str.lastIndexOf(';') != str.length -1){
				str += ';';	
			}
		}
		var i = this.items.nextIndex();
		while(i!=null){
			str += this.items.get(i).toString();
			i = this.items.nextIndex();
		}
		if(str != ''){
			str = 'style="'+str+'"';	
		}
		return str;
	}
}

function StyleItem(_rule,_value){
	this.rule = _rule;	
	this.value = _value;
	this.toString = function(){
		return this.rule + ':' + this.value + ';';	
	}
}

//************** Events 
//*************************************************************************

function Events(){
	this.events = new Collection();
	this.set = function(event,action){
		var i = this.events.nextIndex();
		while(i!=null){
			if(this.events.get(i).event == event){
				this.events.get(i).action = action;
				this.events.currentIndex = 0;
				return;
			}
			i = this.events.nextIndex();
		}
		this.events.add(new AQUAEvent(event,action));
	}
	this.remove = function(event){
		var i = this.events.nextIndex();
		while(i!=null){
			if(this.events.get(i).event == event){
				this.events.remove(i);
				this.events.currentIndex = 0;
				return;
			}
			i = this.events.nextIndex();
		}
	}
	this.toString = function(){
		var str = '';
		var i = this.events.nextIndex();
		while(i!=null){
			str += this.events.get(i).toString() + ' ';
			i = this.events.nextIndex();
		}
		return str;
	}
}

function AQUAEvent(_event, _action){
	this.event = _event;
	this.action = _action;
	this.toString = function(){
		return this.event + '="' + this.action + '"';
	}
}

//************** OptionSelector 
//*************************************************************************

function OptionSelector(_id, _action){
	this.config = new ConfigurationItem();
	this.id = _id;
	this.action = _action;
	this.options = new Array();
	this.setOption = function(key, text){
		for(var i=0;i<this.options.length;i++){
			if(this.options[i].key == key){
				this.options[i] = new OptionItem(key, text);	
				return;
			}
		}
		this.options[this.options.length] = new OptionItem(key, text);	
	}
	this.toString = function(){
		this.config.prepare();
		var s = '<select onchange="'+this.action+'" id="'+this.id+'" class="'+this.config.css+'" '+this.config.style.toString()+'>';
		var options = '';
		for(var i=0;i<this.options.length;i++){
			options	+= '<option value="'+this.options[i].key+'">'+this.options[i].text+'</option>';
		}
		s += options + '</select>';
		return s;
	}
	
}

function OptionItem(_key, _text){
	this.text = _text;
	this.key = _key;
}


//************** DataGrid 
//*************************************************************************


function GridMap(){}
GridMap.instances = new Collection();

function ConfigurationItem(){
	this.height = '';
	this.css = ''; // Css classes to be aplied (Separete each class with a white space)
	this.style = new Style(); // Specific style properties
	this.visible = true;
	this.prepare = function(){
		if(this.visible){
			this.style.setItem("visibility", "visible");	
		}else{
			this.style.setItem("visibility", "hidden");	
		}
	}
}

function DataGridConfig(){
	
	//--DATAGRID
	this.containerConfig = new ConfigurationItem(); 
	this.containerConfig.css = 'aqua-grid-container';
	this.scrollWidth = 17;
	this.showToolTip = true;
	
	//--TABLES
	this.cellspacing = 0;
	this.cellpadding = 0;
	this.borderWidth = 0;
	
	//--FOOTER
	this.footerConfig = new ConfigurationItem();
	this.footerConfig.visible = true;
	this.footerConfig.height = 20;
	this.footerConfig.css = 'aqua-grid-footer';
	
	//--CAPTION
	this.captionConfig = new ConfigurationItem();
	this.captionConfig.css = 'aqua-grid-caption';
	this.captionConfig.height = 20;
	this.captionConfig.style.setItem("text-align","left");
	this.captionConfig.style.setItem("width","50%");
	
	//--HEADER
	this.headerConfig = new ConfigurationItem();
	this.headerConfig.height = 20;
	this.headerConfig.css = 'aqua-grid-header';
	
	//--PAGING
	this.pagingConfig = new ConfigurationItem();
    this.pagingConfig.NextText = 'Next';
    this.pagingConfig.PreviousText = 'Previous';
    this.pagingConfig.NoRowsText = 'No rows to display'; 
	// [FIRST] = index of the first item/row on the actual viewing page
    // [LAST] = index of the last  item/row on the actual viewing page
    // [TOTAL] = total count of items/rows
    this.pagingConfig.text = 'Showing from [FIRST] to [LAST] of [TOTAL]';   // Page Status text
	this.pagingConfig.style.setItem("text-align","right");
	this.pagingConfig.style.setItem("width","50%");
	this.pagingConfig.css = 'aqua-grid-paging';
	
	//-- BODY
	this.bodyConfig = new ConfigurationItem();
	this.bodyConfig.rowHeight = 20;
	this.bodyConfig.css = 'aqua-grid-body';
	
	this.showSelectedRow = true;
	this.selectedRowColor = '#B9CEFF';
	this.showPagesInFooter = true;
	this.navegationText = 'Go to:&nbsp;';
	
	this.prepare = function(){
		this.containerConfig.prepare();
		this.pagingConfig.prepare();
		this.headerConfig.prepare();
		this.bodyConfig.prepare();
		this.footerConfig.prepare();
		this.captionConfig.prepare();
	}
}

function DataGrid(config){
	
	this.selectedIndex = -1;
	this.selectedRow = null;
	this.config = config;
	if(!this.config){
		this.config = new DataGridConfig();	
	}
	
	//--BEHAVIOR 
	this.allowPaging = false;
	this.pageSize = -1; 
	this.autoSelectRow = true;
	
	//--CONTENT
	this.columnHeaders = new Collection();
	this.dataRows = new Collection();
	this.firstIndex = 0;
	this.lastIndex = 0;
	this.parent = null;
	this.id = GridMap.instances.add(this);
	this.gridModel;
	
	//EVENTS
	this.onRender = function(){}
	
	//CONTENT
	this.footer = '&nbsp;';             	// Footers text/html
	this.caption = '&nbsp;';                // Title displayed on the left top corner of the Grid
	this.bodyHeight = -1;
	
	
	//FUNCTIONS
	this.addDataRow = function(){
		var dataRow = new DataRow();
		this.dataRows.add(dataRow);
		return dataRow;
	}

	this.addColumnHeader = function(_html, _w){
		this.columnHeaders.add(new ColumnHeader(_html,_w));
	}
	
	this.getPagingText = function(){
            
		// [FIRST] = index of the first item/row on the actual viewing page
		// [LAST] = index of the last  item/row on the actual viewing page
		// [TOTAL] = total count of items/rows
		
		if(!(this.config.pagingConfig.visible)){
			return '&nbsp;';
		}
		var size = this.dataRows.size();
		if(size < 1){
			return this.config.pagingConfig.NoRowsText;
		}

		var navigation = '';
		var text = '';
		var from = this.firstIndex + 1;
		var to = this.lastIndex + 1;
		
		text = this.config.pagingConfig.text.replace("[FIRST]", from);
		text = text.replace("[LAST]", to);
		text = text.replace("[TOTAL]", size);
		
		if(this.allowPaging){
			if(from > 1){
				navigation += '<a href="javascript:GridMap.instances.get('+this.id+').render(\'prev\');">' + this.config.pagingConfig.PreviousText + '</a>';	
			}if(to < size){
				if(navigation != '') navigation += '&nbsp;-&nbsp;';
				navigation += '<a href="javascript:GridMap.instances.get('+this.id+').render(\'next\');">' + this.config.pagingConfig.NextText + '</a>';
			}
		}
		
		if(navigation != ''){
			navigation = ' (' + navigation + ')';
			text += navigation;
		}
		return text;		
	}
	
	this.render = function(dir){
		var _firstIndex = 0;
		var _lastIndex = this.dataRows.size()-1;
		if(this.allowPaging){
			if(!dir){
				_lastIndex = (this.lastIndex + (this.pageSize) - 1);
				if(_lastIndex >= this.dataRows.size()){
					_lastIndex = this.dataRows.size()-1;
				}
			}else{
				if(dir == 'next'){
					_firstIndex = this.firstIndex + (this.pageSize);
					_lastIndex = this.lastIndex + (this.pageSize);
					if(_lastIndex >= this.dataRows.size()){
						_lastIndex = this.dataRows.size() - 1;
					}	
				}else if(dir == 'prev'){
					_firstIndex = (this.firstIndex - (this.pageSize));
					_lastIndex = (_firstIndex + (this.pageSize)-1);
					if(_firstIndex < 0){
						_firstIndex = 0;
					}
				}
			}
			this.firstIndex = _firstIndex;
			this.lastIndex = _lastIndex;
			this.do_render(_firstIndex, _lastIndex);
		}else{
			this.do_render(_firstIndex, _lastIndex);		
		}
	}
	
	this.do_render = function(_firstIndex, _lastIndex){
		var _link = this.getPagingText();
		var headers = new StringBuilder('<tr>');
		var width = 0;
		var i = this.columnHeaders.nextIndex();
		while(i!=null){
			if(this.gridModel.getIsSortableColumn(i)){
				this.columnHeaders.get(i).style.setItem('text-decoration', 'underline');
				this.columnHeaders.get(i).events.set('onmouseover', 'this.style.textDecoration = \'none\'');
				this.columnHeaders.get(i).events.set('onmouseout', 'this.style.textDecoration = \'underline\'');
				this.columnHeaders.get(i).events.set('onclick', 'GridMap.instances.get('+this.id+').do_sort('+i+')');
			}
			headers.append(this.columnHeaders.get(i).toString());
			width += this.columnHeaders.get(i).width;
			i = this.columnHeaders.nextIndex();
		}
		headers.append('<td class="aqua-grid-scroll"></td></tr>');
		var rows = new StringBuilder('');
		for(var i=_firstIndex;i<=_lastIndex;i++){
			var index = this.dataRows.get(i).dataCells.nextIndex();
			while(index!=null){
				this.dataRows.get(i).dataCells.get(index).style.setItem("width", this.columnHeaders.get(index).width+"px");
				index = this.dataRows.get(i).dataCells.nextIndex();
			}		
			rows.append(this.dataRows.get(i).toString(this.config.showToolTip, this.config.bodyConfig.rowHeight, i, this.id));
		}
		width += parseInt(this.config.borderWidth) + parseInt(this.config.cellspacing * 2) + parseInt(this.config.scrollWidth) + parseInt(this.config.cellpadding * 2);
	    if(this.config.borderWidth > 0) width += (parseInt(this.columnHeaders.size() + 1) * 2) + this.config.borderWidth;
		this.config.containerConfig.style.setItem("width", width + "px");
		this.config.headerConfig.style.setItem("width", (width+this.config.scrollWidth) + "px");
		this.config.bodyConfig.style.setItem("height", ((_lastIndex - _firstIndex)  * this.config.bodyConfig.rowHeight)+"px");
		this.config.bodyConfig.style.setItem("width", width + "px");
		this.config.prepare();
		var html = '<table cellpadding="0" cellspacing="0" border="0" id="aqua_datagrid" '+this.config.containerConfig.style.toString()+' class="'+this.config.containerConfig.css+'">'+
					'	<tr>'+
					'		<td style="height:'+this.config.captionConfig.height+'px;">&nbsp;</td>'+
					'		<td '+this.config.captionConfig.style.toString()+' class="'+this.config.captionConfig.css+'">'+this.caption+'</td>'+
					'		<td '+this.config.pagingConfig.style.toString()+' class="'+this.config.pagingConfig.css+'">'+_link+'</td>'+
					'	</tr>'+
					'	<tr>'+
					'		<td style="height:'+this.config.headerConfig.height+'px;">&nbsp;</td>'+
					'		<td colspan="2">'+
					'				<table '+this.config.headerConfig.style.toString()+' class="'+this.config.headerConfig.css+'" cellpadding="'+this.config.cellpadding+'" cellspacing="'+this.config.cellspacing+'" border="'+this.config.borderWidth+'">'+
					'					<tr>'+
					headers.toString()+
					'					</tr>'+
					'				</table> '+
					'		</td>'+
					'	</tr>'+
					'	<tr>'+
					'		<td style="height:'+this.config.bodyConfig.height+'px;">&nbsp;</td>'+
					'		<td colspan="2">'+
					'			<div style="height:'+this.config.bodyConfig.height+'px; width:'+(width + this.config.scrollWidth)+'px; overflow:auto; margin:0px; text-align:left">'+
					'				<table id="aqua_central_table_'+this.id+'" '+this.config.bodyConfig.style.toString()+' class="'+this.config.bodyConfig.css+'" cellpadding="'+this.config.cellpadding+'" cellspacing="'+this.config.cellspacing+'" border="'+this.config.borderWidth+'">'+
					rows.toString()+
					'				</table> '+
					'			 </div>'+
					'		</td>'+
					'	</tr>';
		if(this.config.footerConfig.visible){
			if(this.allowPaging && this.config.showPagesInFooter){
				html += '	<tr>'+
						'		<td style="height:'+this.config.footerConfig.height+'px;">&nbsp;</td>'+
						'		<td colspan="2" '+this.config.footerConfig.style.toString()+' class="'+this.config.footerConfig.css+'">'+ this.config.navegationText +
						this.getPagesLinks(this.id) +
						'		</td>'+
						'	</tr>';
			}else{
				html += '	<tr>'+
						'		<td style="height:'+this.config.footerConfig.height+'px;">&nbsp;</td>'+
						'		<td colspan="2" '+this.config.footerConfig.style.toString()+' class="'+this.config.footerConfig.css+'">'+
						this.footer +
						'		</td>'+
						'	</tr>';
			}
		}
		html += '</table>';
		this.parent.innerHTML = html;
		if(this.dataRows.size() > 0 && this.allowPaging){
			var i = 1;
			var page_dom = _('grid_'+this.id+'_page_' + i);
			while(page_dom){
				_('grid_'+this.id+'_page_' + i).style.fontWeight = 'normal';
				i++;
				page_dom = _('grid_'+this.id+'_page_' + i);
			}
			var page = (_firstIndex / this.pageSize) + 1;
			_('grid_'+this.id+'_page_'+page).style.fontWeight = 'bold';
		}
		this.onRender();
	}
	
	this.getCellAt = function(rowIndex, cellIndex){
		return _('grid_'+this.id+'_cell_' + rowIndex + '_' + cellIndex);
	}
	
	this.getDataCellAt = function(rowIndex, cellIndex){
		var dr = this.dataRows.get(rowIndex);
		return dr.dataCells.get(cellIndex);
	}
	
	this.setValueAt = function(rowIndex, cellIndex, value){
		this.getCellAt(rowIndex, cellIndex).innerHTML = value;
		this.getDataCellAt(rowIndex, cellIndex).innerHTML = value;
	}
	
	this.setModel = function(gridModel){
		this.gridModel = gridModel;
		this.updateData(true);
		this.gridModel.datagrid = this;
	}
	
	this.updateData = function(updateHeaders){
		var headers = this.gridModel.getColumnsHeaders();
		if(updateHeaders){
			this.columnHeaders.clear();
			for(var index=0;index<headers.length;index++){
				this.addColumnHeader(headers[index], this.gridModel.getHeaderSize(index));
			}
		}
		var collection = this.gridModel.array;
		this.dataRows.clear();
		for(var index=0;index<collection.length;index++){
			var r = this.addDataRow();
			for(var _index=0;_index<headers.length;_index++){
				r.addDataCell(this.gridModel.getValueAt(index,_index));
				var style = this.gridModel.getStyleAt(index,_index);
				if(style){
					var i = style.items.nextIndex();
					while(i!=null){
						var style_item = style.items.get(i);
						r.dataCells.get(_index).style.setItem(style_item.rule, style_item.value);
						i = style.items.nextIndex();
					}	
				}
			}
		}
	}
	
	this.removeDataRow = function(index){
		this.dataRows.remove(index);
		if(this.dataRows.size() > this.lastIndex){
			this.do_render(this.firstIndex, this.lastIndex);
			return;
		}else{
			this.lastIndex--;
			if(this.firstIndex > this.lastIndex){
				this.render('prev');		
				return;
			}
			this.do_render(this.firstIndex, this.lastIndex);
		}
	}
	
	this.selectRow = function(index){
		this.selectedIndex = index;
		if(this.config.showSelectedRow){
			var row = _('grid_'+this.id+'_row_' + index);
			row.style.backgroundColor = this.config.selectedRowColor;
			if(this.selectedRow && row != this.selectedRow){
				var r = this.dataRows.get(index);
				this.selectedRow.style.backgroundColor = r.style.getItem('background-color');
			}
			this.selectedRow = row;
		}
	}
	
	this.goToPage = function(page){
		var pages = this.dataRows.size() / this.config.pageSize;
		pages = Math.round(pages + 0.49);
		if(page > pages){
			throw "Page index out of bounds";	
		}
		var fL = (page * this.pageSize);
		var fI = fL - this.pageSize;
		fL = fL - 1;
		if(fL > (this.dataRows.size()-1)){
			fL = this.dataRows.size()-1;
		}
		this.firstIndex = fI;
		this.lastIndex = fL;
		this.do_render(fI, fL);
		var i = 1;
		var page_dom = _('grid_'+this.id+'_page_' + i);
		while(page_dom){
			_('grid_'+this.id+'_page_' + i).style.fontWeight = 'normal';
			i++;
			page_dom = _('grid_'+this.id+'_page_' + i);
		}
		_('grid_'+this.id+'_page_' + page).style.fontWeight = 'bold';
	}
	
	this.getPagesLinks = function(id){
		var pages = this.dataRows.size() / this.pageSize;
		pages = Math.round(pages + 0.49);
		var str = '';
		var style = 'style="font-weight:bold;"';
		for(var i=1;i<=pages;i++){
			str += '<a '+style+' id="grid_'+this.id+'_page_'+i+'" href="javascript:GridMap.instances.get('+id+').goToPage('+i+')">'+i+'</a>&nbsp;';	
			style = '';
		}
		return str;
	}
	
	this.do_sort = function(headerIndex){
		var s = this.columnHeaders.get(headerIndex).getSorter();
		s.index = headerIndex;
		s.model = this.gridModel;
		s.do_sort();
		this.lastIndex = 0;
		this.firstIndex = 0;
		this.updateData(false);
		this.render();
	}
	
}

function ColumnHeader(_innerHTML, _width){
	this.sorter = null;
	this.innerHTML = _innerHTML;
	this.events = new Events();
	this.style = new Style();
	this.style.setItem("width", _width + "px");
	this.width = _width;
	this.toString = function(){
		return '<td '+this.events.toString()+' '+this.style.toString()+'>'+this.innerHTML+'</td>';
	}
	this.getSorter = function(){
		if(!this.sorter){
			this.sorter = new DataGridSorter();	
		}
		return this.sorter;
	}
}
	
function DataRow(){
	this.dataCells = new Collection();
	this.events = new Events();
	this.style = new Style(); // Specific style for the current row
	this.addDataCell = function(_html){
		this.dataCells.add(new DataCell(_html));
	}	
	this.toString = function(show, rowHeight, _index, id){
		var str = '<tr id="grid_'+id+'_row_'+_index+'" onclick="GridMap.instances.get('+id+').selectRow('+_index+')" '+this.events.toString()+' '+this.style.toString()+'><td style="height:'+rowHeight+'px"></td>';
		var i = this.dataCells.nextIndex();
		while(i!=null){
			str += this.dataCells.get(i).toString(show, _index, i, id);
			i = this.dataCells.nextIndex();
		}
		return str += '</tr>';
	}
}

function DataCell(_innerHTML){
	this.style = new Style(); // Specific style for the current cell
	this.events = new Events();
	this.innerHTML = _innerHTML;
	this.toString = function(showTip, rowIndex, cellIndex, grid_id){
		if(this.innerHTML.indexOf('</') != -1 || this.innerHTML.indexOf('/>') != -1){		
			return '<td id="grid_'+grid_id+'_cell_'+rowIndex+'_'+cellIndex+'" '+this.events.toString()+' '+this.style.toString()+'>'+this.innerHTML+'</td>';	
		}else{
			if(showTip){
				this.events.set('onmouseover', 'ShowTip(event)');
			}
			return '<td id="grid_'+grid_id+'_cell_'+rowIndex+'_'+cellIndex+'" '+this.events.toString()+' '+this.style.toString()+'>'+this.innerHTML+'</td>';
		}
	}
}

function GridModel(array){
	this.array = array;
	this.getIsSortableColumn = function(headerIndex){
		return false;	
	}
	this.getColumnsHeaders = function(){
		throw "This method must be implemented by the custom model";	
	}
	this.getHeaderWidth = function(headerIndex){
		throw "This method must be implemented by the custom model";	
	}
	this.getValueAt = function(rowIndex, cellIndex){
		throw "This method must be implemented by the custom model";	
	}
	this.getDecodedValueAt = function(rowIndex, cellIndex){
		throw "This method must be implemented by the custom model";	
	}
	this.getSortTypeAt = function(rowIndex, cellIndex){
		return DataGridSorter.STRING;	
	}
	this.getStyleAt = function(rowIndex, cellIndex){
		return false;
	}
}

//************** SORTER
//*************************************************************************

var ACTIVE_SORTER = null;
function DataGridSorter(){
	this.index;
	this.model;
	this.dir = 'ASC';
	this.do_sort = function(){
		ACTIVE_SORTER = this;
		AQUA_quick_sort(this.model.array);
		if(this.dir == 'ASC'){
			this.dir = 'DESC';				
		}else{
			this.dir = 'ASC';	
		}
	}
}

DataGridSorter.STRING = 1;
DataGridSorter.INT = 2;
DataGridSorter.FLOAT = 3;
DataGridSorter.DATE = 4;
DataGridSorter.DATE_TIME = 5;

function AQUA_array_swap(array, a, b)
{
	var tmp=array[a];
	array[a]=array[b];
	array[b]=tmp;
	return array;
}


function AQUA_partition(array, begin, end, pivot)
{
	var piv=ACTIVE_SORTER.model.getDecodedValueAt(pivot, ACTIVE_SORTER.index).toLowerCase();
	if(ACTIVE_SORTER.model.getSortTypeAt(ACTIVE_SORTER.index) == DataGridSorter.INT){
		piv = parseInt(piv);	
	}
	array = AQUA_array_swap(array, pivot, end-1);
	var store=begin;
	var ix;
	for(ix=begin; ix<end-1; ++ix) {
		if(ACTIVE_SORTER.dir == 'ASC'){
			var _piv = ACTIVE_SORTER.model.getDecodedValueAt(ix, ACTIVE_SORTER.index).toLowerCase();
			if(ACTIVE_SORTER.model.getSortTypeAt(ACTIVE_SORTER.index) == DataGridSorter.INT){
				_piv = parseInt(_piv);	
			}else if(ACTIVE_SORTER.model.getSortTypeAt(ACTIVE_SORTER.index) == DataGridSorter.FLOAT){
				_piv = parseFloat(_piv);	
			}
			if(_piv<=piv) {
				array = AQUA_array_swap(array, store, ix);
				++store;
			}
		}else{
			var _piv = ACTIVE_SORTER.model.getDecodedValueAt(ix, ACTIVE_SORTER.index).toLowerCase();
			if(ACTIVE_SORTER.model.getSortTypeAt(ACTIVE_SORTER.index) == DataGridSorter.INT){
				_piv = parseInt(_piv);	
			}else if(ACTIVE_SORTER.model.getSortTypeAt(ACTIVE_SORTER.index) == DataGridSorter.FLOAT){
				_piv = parseFloat(_piv);	
			}
			if(_piv>=piv) {
				array = AQUA_array_swap(array, store, ix);
				++store;
			}
		}
	}
	array = AQUA_array_swap(array, end-1, store);
	return store;
}


function AQUA_qsort(array, begin, end)
{
	if(end-1>begin) {
		var pivot=begin+Math.floor((end-begin)/2);
		pivot=AQUA_partition(array, begin, end, pivot);
		AQUA_qsort(array, begin, pivot);
		AQUA_qsort(array, pivot+1, end);
	}
}


function AQUA_quick_sort(array)
{
	AQUA_qsort(array, 0, array.length);
}

	
//************** AJAX 
//*************************************************************************

var error_url = 'feedback.jsp';

function AQUAX(){
	this.xhr = null;
	this.method;
	this.url;
	this.params = new Array();
	this.callback_method;
	this.addParam = function(key,value){
		this.params[this.params.length] = new Param(key,value);
	}
	this.send = function(){
		var _url = '?ajax=true';
		for(var i=0;i<this.params.length;i++){
			_url += this.params[i];	
		}
		this.xhr = newXMLHttpRequest();
		var oncallback = this.oncallback;
		var callback_method = this.callback_method;
		var _xhr = this.xhr;
		if(this.method == AQUAX.GET){
			this.xhr.open(this.method, this.url + _url, true);
			this.xhr.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
			this.xhr.onreadystatechange = function(){oncallback(callback_method, _xhr);}
			this.xhr.send(null);
		}else if(this.method == AQUAX.POST){
			this.xhr.open(this.method, this.url, true);
			this.xhr.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"); 
			this.xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
			this.xhr.setRequestHeader("Content-length", _url.replace('?','').length);
			this.xhr.setRequestHeader("Connection", "close");	
			this.xhr.onreadystatechange = function(){oncallback(callback_method, _xhr);}
			this.xhr.send(_url.replace('?',''));
		}else{
			throw "Invalid Ajax method";	
		}
	}
	this.oncallback = function(callback_method, _xhr){
		if (_xhr.readyState == 4) {
			var text = _xhr.responseText;
			var object = eval('('+text+')');
			if(object.type == "error"){
				window.onbeforeunload = function(){}
				document.location.href = error_url;
			}else if(object.type == "ok"){
				callback_method(object);
			}
		}	
	}
}

AQUAX.GET = "GET";
AQUAX.POST = "POST";

function Param(_key, _value){
	this.key = _key;
	this.value = _value;
	this.toString = function(){
		if(!this.value.serialize){
			return "&" + this.key + "=" + this.value;
		}else{
			return "&" + this.key + "=" + this.value.serialize();
		}
	}
}

function newXMLHttpRequest(){
	try {
		var xhr = new ActiveXObject("Msxml2.XMLHTTP");
	} catch (e) {
		try {
			xhr = new ActiveXObject("Microsoft.XMLHTTP");
		} catch (E) {
			xhr = false;
		}
	}
	if (!xhr && typeof XMLHttpRequest != 'undefined') {
		xhr = new XMLHttpRequest();
	}
	return xhr;
}

//************** DIALOG 
//*************************************************************************

var AQUA_CD_focusedElement = null;

function ConfirmDialog(){
	
	this.height = 100;
	this.width = 500;
	this.actions = new Array();
	this.text;
	this.img;
	this.focusableItems = new Array();
	this.addAction = function(img, text, action){
		this.actions[this.actions.length] = new ConfirmAction(text, img, action);
		return 'dialog_action_' + (this.actions.length-1);
	}
	this.show = function(img, text){
		this.text = text;
		this.img = img;
		var div = document.createElement('div');
		div.id = 'screen_block';
		var container = document.createElement('div');
		container.id = 'dialog_container'; 
		var dialog = document.createElement('div');
		dialog.id = 'dialog_div';
		dialog.className = 'dialog_div';
		dialog.style.height = this.height + 'px';
		dialog.style.width = this.width + 'px';
		container.innerHTML = '<table id="table_dialog" cellpadding="0" border="0" cellspacing="0">'+
							  '    <tr><td style="width:1px;"></td>'+
							  '    <td id="cell_dialog"></td></tr>'+
							  '</table>';
		container.appendChild(dialog);
		container.onclick = function(event){
			var src = null;
			if(window.event){
				src = window.event.srcElement;
			}else{
				src = event.target;	
			}
			if(src.id == 'cell_dialog'){
				_SHOW(4,true);	
			}
		}
		_('body','tag')[0].appendChild(div);
		_('body','tag')[0].appendChild(container);
		document.getElementById('cell_dialog').appendChild(dialog);
		this.paint(text);
		_SHOW(4, true);
	}
	this.hide = function(){
		if(_('dialog_container')){
			_('body','tag')[0].removeChild(_('dialog_container'));
			_('body','tag')[0].removeChild(_('screen_block'));
			var nav = navigator.userAgent;
			if(nav.indexOf('MSIE') != -1){			
				var b = _('body', 'tag')[0];
				b.onkeydown = function(){window.event.returnValue = true;}
			}else{
				window.onkeydown = function(evt){return true;}
			}
		}
	}
	this.paint = function(){
		var html = '';
		if(this.actions.length > 0){
			var actions = '';
			for(var i=0;i<this.actions.length;i++){
				actions += '<td  class="table_dialog_action"><input id="dialog_action_'+i+'" onclick="'+this.actions[i].action+'" onmouseover="this.className = \'dialog_action_button_on\'" onmouseout="this.className = \'dialog_action_button\'" type="button" class="dialog_action_button" style="background-image:URL('+this.actions[i].image+')" value="'+this.actions[i].text+'" /></td><td class="dialog_sep"></td>';
			}
			html = '<table cellspacing="0" cellpadding="0" border="0" style="margin:0 auto;">'+
					   '	<tr>'+actions +
					   '	</tr>'+
					   '</table>';
			
		}
		_('dialog_div').innerHTML = '<table cellspacing="0" cellpadding="0" border="0">'+
						   '	<tr>'+
						   '		<td class="dialog_img"><img id="dialog_img" src="'+this.img+'" /></td>'+
						   '		<td id="dialog_text" style="width:'+this.width+'px">'+this.text+'</td>'+
						   '	</tr>'+
						   '	<tr>'+
						   '		<td colspan="2" style="height:15px;">'+
						   '		</td>'+
						   '	<tr>'+
						   '		<td colspan="2" id="dialog_actions">'+html+
						   '		</td>'+
						   '	</tr>'+
						   '</table>';
		var nav = navigator.userAgent;
		if(nav.indexOf('MSIE') != -1){
			_('dialog_div').focus();
			var b = _('body', 'tag')[0];
			b.onkeydown = function(){
				var evt = window.event;	
				var charCode = (evt.which) ? evt.which : evt.keyCode;
				if(charCode == 9){
					AQUA_CD_focusElement();	
					evt.cancelBubble = true;
					evt.returnValue = false;
				}			
			}
		}else{
			document.getElementsByTagName("body")[0].blur();
			window.onkeydown = function(evt){
				var charCode = (evt.which) ? evt.which : evt.keyCode;
				if(charCode == 9){
					AQUA_CD_focusElement();
					evt.preventDefault();
				}
			}
		}
		AQUA_CD_focusedElement = null;
		AQUA_CD_focusElement();
	}
}

function AQUA_CD_focusElement(){
	AQUA_CD_setNextFocusedElement();
	if(AQUA_CD_focusedElement){
		AQUA_CD_focusedElement.focus();
	}else{
		AQUA_CD_setNextFocusedElement();
		if(AQUA_CD_focusedElement){
			AQUA_CD_focusedElement.focus();	
		}
	}
}

function AQUA_CD_setNextFocusedElement()
{
  var domElement = _('dialog_div');
  AQUA_CD_setNextFocusedElement_rec(domElement, 1);
}

function AQUA_CD_setNextFocusedElement_rec(currentElement, depth)
{
  if (currentElement)
  {
    var j;
    var tagName=currentElement.tagName;
	if(tagName){
		var disabled = currentElement.disabled;
		if(tagName.toLowerCase() == 'a' || tagName.toLowerCase() == 'input' || tagName.toLowerCase() == 'select' || tagName.toLowerCase() == 'textarea' || tagName.toLowerCase() == 'button' || tagName.toLowerCase() == 'object'){
			if(!disabled){
				if(AQUA_CD_focusedElement == null){
					AQUA_CD_focusedElement = currentElement;
					AQUA_CD_focusedElement.setAttribute('focused', "focused");
					return;
				}else if(currentElement.getAttribute('focused') != null){
					if(currentElement.getAttribute('focused') == "focused"){
						currentElement.setAttribute('focused', null);
						AQUA_CD_focusedElement = null;
					}
				}
			}
		}
	}
    var i=0;
    var currentElementChild=currentElement.childNodes[i];
    while (currentElementChild)
    {
      AQUA_CD_setNextFocusedElement_rec(currentElementChild, depth+1);
      i++;
      currentElementChild=currentElement.childNodes[i];
    }
  }
}

function _SHOW(i, v){
	if(_('dialog_div')){
		if(v){
			_('dialog_div').className = 'dialog_div';
		}else{
			_('dialog_div').className = 'dialog_div dialog_div_off';
		}
		if(i>0){
			window.setTimeout('_SHOW('+(i-1)+', '+!v+')', 50);
		}
	}
}

function ConfirmAction(_text, _image, _action){
	this.image = _image;
	this.text = _text;
	this.action = _action;
}


//************** TRANSPORT 
//*************************************************************************


function Transport(_class){
	this._class = _class;
	this.properties = new Array();
	this.objects = new Array();
	this.setProperty = function(key, value){
		for(var i=0;i<this.properties.length;i++){
			if(this.properties[i].key == key){
				this.properties[i] = new TransportProperty(key, value);	
				return;
			}
		}
		this.properties[this.properties.length] = new TransportProperty(key, value);	
	}
	this.setObject = function(key, o){
		for(var i=0;i<this.objects.length;i++){
			if(this.objects[i].key == key){
				this.objects[i] = new TransportObject(key, o);
				return;
			}
		}
		this.objects[this.objects.length] = new TransportObject(key, o);
	}
	this.removeObject = function(key){
		for(var i=0;i<this.objects.length;i++){
			if(this.objects[i].key == key){
				this.objects.splice(i, 1);
				return;
			}
		}
	}
	this.removeProperty = function(key){
		for(var i=0;i<this.properties.length;i++){
			if(this.properties[i].key == key){
				this.properties.splice(i, 1);
				return;
			}
		}
	}
	this.getProperty = function(key){
		for(var i=0;i<this.properties.length;i++){
			if(this.properties[i].key == key){
				return this.properties[i].value;
			}
		}
		return null;
	}
	this.getObject = function(key){
		for(var i=0;i<this.objects.length;i++){
			if(this.objects[i].key == key){
				return this.objects[i].value;
			}
		}
		return null;
	}
	this.toXML = function(){
		var obj = '<object class="ultrod.util.transport.Transport">';
		obj += '<void property="_class"><string>'+this._class+'</string></void>';
		
		var strprops = '<object class="java.util.ArrayList">';
		for(var i=0;i<this.properties.length;i++){
			strprops += '<void method="add"><object class="ultrod.util.transport.TransportProperty">'+
			'<void property="key"><string>'+this.properties[i].key+'</string></void>'+
			'<void property="value"><string>'+this.properties[i].value.getDecimalEncodedValue()+'</string></void></object></void>';
		}
		strprops += '</object>';		
		var strobjs = '<object class="java.util.ArrayList">';
		for(var i=0;i<this.objects.length;i++){
			var _obj = this.objects[i];
			strobjs += '<void method="add"><object class="ultrod.util.transport.TransportObject">'+
			'<void property="key"><string>'+_obj.key+'</string></void>';
			var list = "";
			if(_obj.value.constructor.toString().indexOf("function Transport") != -1){
				list = _obj.value.toXML();
			}else if(_obj.value.constructor.toString().indexOf("function Array") != -1){
				list = '<object class="java.util.ArrayList">';
				for(var c=0;c<_obj.value.length;c++){
					if(_obj.value[c].toXML){
						list += '<void method="add">' + _obj.value[c].toXML() + '</void>';	
					}
				}	
				list += '</object>';
			}
			strobjs += '<void property="value">'+list+'</void></object></void>';
		}
		strobjs += '</object>';
		obj += '<void property="properties">'+strprops+'</void>';
		obj += '<void property="objects">'+strobjs+'</void>';
		obj += '</object>';
		return obj;

	}
	this.serialize = function(){
		var xml = '<?xml version="1.0" encoding="UTF-8"?><java version="1.5.0_04" class="java.beans.XMLDecoder">' + this.toXML() + '</java>';
		return xml;
	}
	this.save = function(callback, do_reload){
		var ajax = new AQUAX();
		ajax.method = AQUAX.POST;
		ajax.url = '../servlets/SrvGeneral';
		ajax.callback_method = callback;
		ajax.addParam('reload', do_reload);
		ajax.addParam('Transport', this);
		ajax.send();
	}
}

function TransportProperty(_key, _value){
	this.key = _key;
	this.value = new Encoder(_value);
}

function TransportObject(_key, _value){
	this.key = _key;
	this.value = _value;
}

Transport.parseObject = function(_t){
	var t = new Transport(_t._class);
	for(var i=0;i<_t.properties.length;i++){
		t.setProperty(_t.properties[i].key, _t.properties[i].DECIMALEncodedValue);
	}
	for(var i=0;i<_t.objects.length;i++){
		t.setObject(_t.objects[i].key, _t.objects[i].value);
	}
	return t;
}

Transport.parseList = function(list){
	var _list = new Array();
	for(var i=0;i<list.length;i++){
		_list[i] = Transport.parseObject(list[i]);	
	}
	return _list;
}

//************** ENCODER 
//*************************************************************************

function Encoder(s){
	var original_value = s;
	original_value = decode();
	var dec_encoded_value = null;
	var html_encoded_value = null;
    this.getDecodedValue = function(){
		return original_value;
	}
	this.getDecimalEncodedValue = function(){
		if(dec_encoded_value == null){
			dec_encoded_value = encode(Encoder.Types.DEC);
		}
		return dec_encoded_value;
	}
	this.getHTMLEncodedValue = function(){
		if(html_encoded_value == null){
			html_encoded_value = encode(Encoder.Types.HTML);
		}
		return html_encoded_value;
	}
	this.getDecodedValue = function(){
		return decode();
	}
	function encode(type){
		if(original_value.length > 0){
			if(type == Encoder.Types.DEC){
				var encoded = "";
				for(var i=0;i<original_value.length;i++){
					encoded += original_value.charCodeAt(i) + ",";
				}
				return "DEC:ENCODED:" + encoded.substring(0, encoded.length - 1);	
			}else if(type == Encoder.Types.HTML){
				var encoded = "";
				for(var i=0;i<original_value.length;i++){
					if(original_value.charCodeAt(i) == 10){
						encoded += "<br />";
					}else{
						encoded += "&#" + original_value.charCodeAt(i) + ";";
					}
				}
				return encoded;
			}
		}else{
			return "";	
		}
	}
	function decode(){
		if(original_value.indexOf("ENCODED") == -1){
			return original_value;	
		}else{
			var codes = original_value.replace("DEC:ENCODED:", "");
			codes = codes.split(",");
			var decoded = "";
			for(var i=0;i<codes.length;i++){
				decoded += String.fromCharCode(codes[i]);
			}
			return decoded;	
		}
	}
}

Encoder.Types = function(){}
Encoder.Types.DEC = 1;
Encoder.Types.HTML = 2;
Encoder.Types.DECODED = 3;


//************** Drop Down Menu 
//*************************************************************************

function DropDownMenu(_id, _width, _title, _cell_cssOn, _cell_cssOff){
	this.DOM = null;
	this.id = _id;
	this.title = _title;
	this.width = _width;
	this.menuItems = new ItemCollection(this);
	this.cell_cssOn = _cell_cssOn;
	this.cell_cssOff = _cell_cssOff;
	this.show = function(top,left){
		if(this.DOM == null){
			var table = document.createElement("table");
			table.id = "ultrod_DDM";
			table.style.width = this.width + "px";
			table.cellPadding = "0px";
			table.cellSpacing = "0px";
			table.border = 0;
			var row = null;
			var cell = null;
			if(this.title != null){
				row = table.insertRow(-1);
				cell = row.insertCell(-1);
				cell.innerHTML = "&nbsp;" + this.title;
				row.id = "header_DDM"
			}
			for(var i=0;i<this.menuItems.size();i++){
				var item = this.menuItems.at(i);
				row = table.insertRow(-1);	
				cell = row.insertCell(-1);
				DDM_addLinkEvents(cell, item, this);
				row.className = "row_DDM";
				cell.className = this.cell_cssOff;
				var link = document.createElement("div");
				cell.id = 'link_DDM' + i;
				link.className = "link_DDM";
				cell.style.verticalAlign = "middle";
				cell.valign = "middel";
				link.href = 'javascript:void(0)';
				cell.appendChild(link);
				link.style.width = this.width;
				link.innerHTML = '<div><table cellspacing="0" cellpadding="0" border="0" class="table_link_DDM">'+
								    '<tr>'+
									'	<td rowspan="2"><img id="img_DDM'+i+'" src="'+item.iconoff+'" border="0" /></td>'+
									'	<td class="cell_text_DDM">'+item.text+'</td>'+
									'</tr>'+
									'<tr>'+
									'	<td class="cell_help_DDM">'+item.help+'</td>'+
									'</tr>'+
								 '</table></div>';
			}
			this.DOM = table;
		}
		var owner = document.createElement("div");
		owner.style.position = 'absolute';
		owner.style.left = left + "px";
		owner.style.top = top + "px";
		owner.appendChild(this.DOM);
		owner.id = this.id;
		owner.className = "faded_DDM";
		DDM_addEvents(owner);
		if(document.getElementById(this.id)){
			this.hide();						   
		}
		document.getElementsByTagName("body")[0].appendChild(owner);
		if(navigator.userAgent.indexOf('MSIE') != -1){
			owner.focus();
		}else{
			document.getElementsByTagName("body")[0].blur();
		}
	}
	this.hide = function(){
		if(document.getElementById(this.id)){
			document.getElementsByTagName("body")[0].removeChild(document.getElementById(this.id));
		}
	}
}

function DDM_addLinkEvents(cell, item, dmm){
	cell.onmouseover = function(){ 
		cell.className = ddm.cell_cssOn; 
		_(cell.id.replace('link_DDM', 'img_DDM')).src = item.iconon;
	}
	cell.onmouseout = function(){ 
		cell.className = ddm.cell_cssOff; 
		_(cell.id.replace('link_DDM', 'img_DDM')).src = item.iconoff;
	}
	cell.onclick = function(){ document.location.href = item.action; } 
}

function DDM_addEvents(owner){
	owner.onmouseover = function(){
		hide_menu = false;	
	}
	owner.onmouseout = function(){
		var id = owner.id.substring(4,owner.id.length);
		hideMenu(id);
	}
}

function ItemCollection(_owner){
	this.owner = _owner;
	items = new Array();
	this.add = function(text, action, help, iconon, iconoff){
		var item = new Item(text, action, help, iconon, iconoff);
		items[items.length] = item;
		this.owner.DOM = null;
	}
	this.at = function(index){
		try{
			return items[index];	
		}catch(E){
			alert("Index out of bounds");
		}
	}
	this.size = function(){
		return items.length;	
	}
}

function Item(_text, _action, _help, _iconon, _iconoff){
	this.text = _text;
	this.action = _action;
	this.help = _help;
	this.iconon = _iconon;
	this.iconoff = _iconoff;
}

//************** UTILITIES 
//*************************************************************************

var hasErrors = false;

function showError(element, iserror, fieldid){
	var label = _('label_' + element.id);
	var req = _(fieldid);
	if(iserror){
		label.style.color = 'Red';
		req.style.color = 'Red';
		hasErrors = true;
	}else{
		label.style.color = '#2C2829';
		req.style.color = '#2C2829';
	}
}

function getPositionLeft(This){
	var el = This;var pL = 0;
	while(el){pL+=el.offsetLeft;el=el.offsetParent;}
	return pL
}
function getPositionTop(This){
	var el = This;var pT = 0;
	while(el){pT+=el.offsetTop;el=el.offsetParent;}
	return pT
}

function _(text, type){
	if(type == 'tag'){
		return document.getElementsByTagName(text);
	}else if(type == 'name'){
		return document.getElementsByName(text);
	}else{
		return document.getElementById(text);
	}
}

function isEmpty(cadena){ 		                                  
	var blanco = " \n\t" + String.fromCharCode(13); 		                                     
	var i;                         
	var es_vacio;                
	for(i = 0, es_vacio = true; (i < cadena.length) && es_vacio; i++) 
	  es_vacio = blanco.indexOf(cadena.charAt(i)) != - 1;
	return(es_vacio);
}

function isValidMail(cadena){
	ExpresionRegular=/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
	return ExpresionRegular.test(cadena);
}

function ismaxlength(obj, event, contador){
	var maxlength = parseInt(obj.getAttribute('lengthMax'));
	
	if(obj.value.length>maxlength){
		obj.value = obj.value.substring(0, maxlength);
	}
	if(contador){
		doCount(obj, contador);
	}
}

function doCount(obj, contador){
	var element = document.getElementById(contador);
	var num = parseInt(obj.getAttribute("length"));
	num = num - obj.value.length;
	if(element)
	element.innerHTML = num;
}

function isNumberKey(evt){
	 var charCode = (evt.which) ? evt.which : evt.keyCode
	 if (charCode > 31 && (charCode < 48 || charCode > 57)){
		return false;
	 }else{
	 	return true;
	 }
}

function isEnterKey(evt){
	 var charCode = (evt.which) ? evt.which : evt.keyCode
	 return charCode == 13;
}

var alert_element;
function _ALERT(_element, text){
	alert_element = _element;
	if(text != null && text != 'undefined'){
		alert_element.innerHTML = text;	
	}
	__ALERT(4, true);
}


function __ALERT(i, v){
	if(v){
		alert_element.style.visibility = 'visible';
	}else{
		alert_element.style.visibility = 'hidden';
	}
	if(i>0){
		window.setTimeout('__ALERT('+(i-1)+', '+!v+')', 50);
	}
}



function isValidAttach(file, extArray) {
	allowSubmit = false;
	if (!file) return false;
	while (file.indexOf("\\") != -1){
		file = file.slice(file.indexOf("\\") + 1);
		}
		ext = file.slice(file.lastIndexOf(".")).toLowerCase();
		for (var i = 0; i < extArray.length; i++) {
			if (extArray[i] == ext) { allowSubmit = true; break; }
		}
	
	return allowSubmit;
}

function isSecureFormat(txt){
	SecureExpression=/(?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{0,15})$/;
	return SecureExpression.test(txt);
}

function isMoneyKey(evt, txt){	
	 var charCode = (evt.which) ? evt.which : evt.keyCode
	 if (charCode > 38 && (charCode < 48 || charCode > 57) && charCode != 46){
		return false;
	 }else{
		if(charCode == 46){
			if(txt.value.indexOf('.') != -1){
				return false;
			}else{
				return true;
			}
		}else{
			return true;	
		}
	 }
}

function checkMoney(c){
	if(c.value.endsWith('.')){
		c.value = c.value.replace('.','');	
	}
}

function ShowTip(e){
	if(e.target){
		Tip(e.target.innerHTML);	
	}else{
		Tip(window.event.srcElement.innerHTML);
	}	
}

function setFocus(id){
	_(id).focus();
	_(id).select();
}

function setActiveStyleSheet(id, name) {
  var i, a;
  for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
    if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("id")  && a.getAttribute("name")) {
	  if(a.getAttribute("name") == name){
		  a.disabled = true;
		  if(a.getAttribute("id") == id) a.disabled = false;
	  }
    }
  }
}

function getActiveStyleSheet() {
  var i, a;
  for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
    if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title") && !a.disabled) return a.getAttribute("title");
  }
  return null;
}

