var sysJs;
var addRowButton;
var ConfigIds;

var hoveredRow;

var DataCells = ['watts_idle', 'watts_sleep', 'watts_off', 'kwatts_yr', 'kg_co2_yr', 'btu_hr'];

var ConfigFormStates = new Hash();

var random 		= {'min': 1000000, 'max': 2000000 };
var settings 	= {'confirmDelete' : false, 'useContextMenu': false };

var sysCommon = new Class({
    initialize: function(){
		thisObj = this;
		
		thisObj.setAddRowActions();
		thisObj.setKwhCostActions();
		
		thisObj.setRowConfigIds();
		thisObj.setMasterPcTypeList();
		thisObj.setMasterEnvTypeList();
		
		thisObj.insertDataRow(true);

    },
    setKwhCostActions: function(){
    	costField = $('kwh-cost');
    	costField.addEvent('keyup', function(e){
			thisObj.updateRowCosts();
		});
    },
    
    updateRowCosts: function(){
    	thisObj.getDataRows().each(function(row, i){
    		thisObj.insertCostsData(row);
    	});
    },
    setAddRowActions: function(){
    	addRowButton = $('add-row');
		addRowButton.addEvent('click', function(e){
			thisObj.insertDataRow();
		});
		addRowButton = $('add-row-follow');
		addRowButton.addEvent('click', function(e){
			thisObj.insertDataRow();
		});
    },
    
    setMasterPcTypeList: function() {
    	thisObj.setRowPcList(thisObj.getRowId($('config['+thisObj.getRowIdFromArray('last')+']')));
    },
    
    setMasterEnvTypeList: function() {
    	thisObj.setRowEnvList(thisObj.getRowId($('config['+thisObj.getRowIdFromArray('last')+']')));
    },
    
    setRowConfigIds: function(){
    	ConfigIds = [];
    	thisObj.getDataRows().each(function(row, i){
    		ConfigIds.include(thisObj.getRowId(row));
    	});
    },
    
    insertDataRow: function(locked){
    	
    	var newRowId = thisObj.getRandomRowId();
    	
    	//Data Row
    	var rowClone = $('config['+thisObj.getRowIdFromArray('last')+']').clone().inject('data-table-content', 'bottom');
    	rowClone.set('id', 'config['+newRowId+']');
    	if(!locked) thisObj.getRowDeleteButton(rowClone).removeClass('locked');
    	
    	
    	//Edit Row
    	var rowEditClone = $('config-edit['+thisObj.getRowIdFromArray('last')+']').clone(true, true).inject('data-table-content', 'bottom');
    	rowEditClone.set('id', 'config-edit['+newRowId+']');
    	rowEditClone.getElement('.edit-wrapper').addClass('hidden');
    	
    	thisObj.setRowConfigIds();
    	
    	thisObj.setNewRowActions(rowClone);
    	
    	rowClone.removeClass('hidden');
    	rowEditClone.removeClass('hidden');
    	
    	//create new form state
    	thisObj.setRowFormState(rowClone);
    	
    	if (thisObj.countDataRows() > 2)
    		$('del-row-help').removeClass('hidden');
    },
    
    editDataRow: function(id){
    	rowObj = $('config-edit['+id+']').getElement('.edit-wrapper');

    	if (rowObj.hasClass('hidden')) {
    		thisObj.closeAllEdits(id);
    		$('help-wrapper').addClass('hidden');
    		rowObj.removeClass('hidden');
    	} else {
    		thisObj.closeAllEdits(id);
    		$('help-wrapper').removeClass('hidden');
    	}
    	
    	
    },
    
    closeAllEdits: function(id){
    	thisObj.getDataEditRows().each(function(row, i){
    		row.getElement('.edit-wrapper').addClass('hidden');
    	});
    },
    
    deleteDataRow: function(id){
		if (!settings.confirmDelete || confirm("This cannot be undone, are you sure?")){
			$('config['+id+']').dispose();
			$('config-edit['+id+']').dispose();
		}
		thisObj.deleteRowFormState(id);
    	thisObj.setRowConfigIds();
    	
    	if (thisObj.countDataRows() <= 2)
    		$('del-row-help').addClass('hidden');
    },
    
    setRowPcList: function(id){
    	pcTypes.each(function(item, i){
    		$('config-edit['+id+']').getElement('select[name=pc-type]').addOption(item.desc, item.id);
    	});
    },
    
    setRowEnvList: function(id){
    	envTypes.each(function(item, i){
    		$('config-edit['+id+']').getElement('select[name=env-type]').addOption(item.desc, item.id);
    	});
    },
    
    calcCostPerYear: function(row){
    	kwhPerYr 	= $('config['+thisObj.getRowId(row)+']').getElement('input[name=kwatts_yr]').get('value');
    	costPerKwh 	= $('kwh-cost').get('value');
    	
    	totalCost = parseFloat(kwhPerYr)*costPerKwh;
    	
    	return totalCost;
    },
    
    setNewRowActions: function(row){
    	thisObj.getRowEditButton(row).addEvent('click', function(e, i){
    		thisObj.editDataRow(thisObj.getRowId(row));
    	});
    	if (thisObj.getRowEditLink(row)){
	    	thisObj.getRowEditLink(row).addEvent('click', function(e, i){
	    		e.stop();
	    		thisObj.editDataRow(thisObj.getRowId(row));
	    	});
    	}
    	thisObj.getRowDeleteButton(row).addEvent('click', function(e, i){
    		thisObj.deleteDataRow(thisObj.getRowId(row));
    	});
    	thisObj.getRowDoneButton(row).addEvent('click', function(e, i){
    		if (thisObj.validateConfig(row)){
	    		thisObj.setRowFormState(row);
	    		if (thisObj.updateEnergyData(row)) {
	    			thisObj.insertSpecDesc(row);
	    			thisObj.insertCostsData(row);
	    			thisObj.editDataRow(thisObj.getRowId(row));
	    		}
    		}
    		
    	});
    	thisObj.getRowCancelButton(row).addEvent('click', function(e, i){
    		thisObj.editDataRow(thisObj.getRowId(row));
    		thisObj.hideErrors(row);
    		thisObj.applyRowFormState(row);
    		thisObj.loadEnvDesc(row);
    	});
    	
    	thisObj.getPcTypeSelect(row).addEvent('change', function(e, i){
    		thisObj.loadConfigOptions(row);
    	});
    	
    	thisObj.getEnvTypeSelect(row).addEvent('change', function(e, i){
    		thisObj.loadEnvDesc(row);
    	});
    	
    	row.addEvent('mouseover', function(e, i){
    		hoveredRow = $('config['+thisObj.getRowId(this)+']').get('id');
    		
    	});
    	row.addEvent('mouseout', function(e, i){
    		//$('config['+thisObj.getRowId(row)+']').removeClass('hover');
    	});
    },
    
    hilightHoveredDataRow: function(){
    	if ($(hoveredRow) && settings.useContextMenu)
    		$(hoveredRow).toggleClass('hover');

    },
    
    insertCostsData: function(row){
    	$('config['+thisObj.getRowId(row)+']').getElement('td.cost_per_yr').set('html', '&pound;'+thisObj.calcCostPerYear(row).toFixed(2));
    },
    
    validateConfig: function(row){
    	thisObj.hideErrors(row);
    	//nothing should be null
    	var errors = false;
    	
    	thisObj.getRowSelectObjs(row).each(function(select, i){
    		if (select.get('name') == 'pc-type' && select.getSelected().get('value') == 'null'){
    			thisObj.showError(row, 'pc-type');
    			errors = true;
    		} else if(select.getSelected().get('value') == 'null' && !errors) {
    			thisObj.showError(row, select.get('name'));
    			errors = true;
    		}
    	});
    	return (!errors);
    },
    
    showError: function(row, field){
    	$('config-edit['+thisObj.getRowId(row)+']').getElement('select[name='+field+']').getParent().getElement('span.error').setStyle('display', 'block');
    },
    hideErrors: function(row){
    	$('config-edit['+thisObj.getRowId(row)+']').getElements('span.error').each(function(error, i){
    		error.setStyle('display', 'none');
    	});
    },
    
    insertSpecDesc: function(row){
    	
    	descHash = new Hash();
    	descStr = '<strong>Components: </strong>';
    	
    	//foreach select, get the description
    	thisObj.getRowSelectObjs(row).each(function(select, i){
    		descHash.set(select.get('name'), select.getSelected().get('text')); 
    	});
    	
    	descHash.each(function(val, key){
    		if (key == 'pc-type')
    			descStr += val;
    		else
    			descStr += ' / '+val;
    	});
    	
    	qty = $('config-edit['+thisObj.getRowId(row)+']').getElements('input[name=pc-qty]').get('value');
    	descStr += '<br /><strong>Qty: </strong>'+qty;
    	//get the env type
    	envType = thisObj.getEnvTypeSelectVal(row, false, true);
    	
    	descStr += ' - <strong>Environment: </strong>'+envType;
    	row.getElement('td.spec').set('html', descStr);
    },
    
    //start the config functions
    
    loadConfigOptions: function(row, override){
    	
    	thisObj.disableConfigSelects(row);
    	
    	pcTypeId 	= thisObj.getPcTypeSelectVal(row, override);
    	pcTypeDesc 	= thisObj.getPcTypeSelectVal(row, override, true);
    	
    	//get Ajax data
    	var req = thisObj.doJsonReq(row, {
    		'url': 'configoptions/'+pcTypeId,
    		'reqMsg': 'Loading data for '+pcTypeDesc+'...',
    		'reqFailMsg': 'Request failed! Please try again.'
    	});
    	
    	if (req.responseFail)
    		return false;
    	
    	JSON.decode(req.responseText).each(function(part, i){
    		thisObj.loadConfigSelect(row, part.field, part.options);
    	});
    	
    	if (pcTypeId != 'null')
    		thisObj.enableConfigSelects(row);
    	
    	thisObj.clearEditFormResponse(thisObj.getRowId(row));

    },
    
    loadEnvDesc: function(row){
    	thisObj.getRowEnvDescWrapper(row).setStyle('display', 'none');
    	
    	envTypeId 	= thisObj.getEnvTypeSelectVal(row);
    	envTypeDesc 	= thisObj.getEnvTypeSelectVal(row, false, true);
    	
    	//get Ajax data
    	var req = thisObj.doJsonReq(row, {
    		'url': 'envdesc/'+envTypeId,
    		'reqMsg': 'Loading data for '+envTypeDesc+'...',
    		'reqFailMsg': 'Request failed! Please try again.'
    	});
    	
    	if (req.responseFail)
    		return false;
    	
    	data = req.responseText;
    	
    	
    	thisObj.getRowEnvDescWrapper(row).set('html', data);
    	
    	if (envTypeId != 'null')
    		thisObj.getRowEnvDescWrapper(row).setStyle('display', 'block');
    	
    	thisObj.clearEditFormResponse(thisObj.getRowId(row));
    },
    
    getRowEnvDescWrapper: function(row){
    	return $('config-edit['+thisObj.getRowId(row)+']').getElement('div[id=env-response]');
    },
    deleteRowFormState: function(id){
    	ConfigFormStates.erase(id);
    },
    
    setRowFormState: function(row){
    	var stateArray = new Hash();
    	thisObj.getRowSelectObjs(row).each(function(select, i){
    		stateArray.set(select.get('name'), select.getSelected().get('value')); 
    	});
    	ConfigFormStates.set(thisObj.getRowId(row), stateArray);
    },
    
    applyRowFormState: function(row){
    	var rowStateArray = ConfigFormStates.get(thisObj.getRowId(row));
    	
    	rowStateArray.each(function(value, key){
    		if (key == 'pc-type') thisObj.loadConfigOptions(row, value);
    		thisObj.getRowSelectObj(row, key).getElement('option[value='+value+']').set('selected', true);
    	});
    },
    
    enableConfigSelects: function(row){
    	thisObj.getRowSelectObjs(row).each(function(select, i){
    		if (select.get('id') != 'pc-type' && select.get('id') != 'env-type')
    			select.set('disabled', false);
    	});
    	
    },
    
    disableConfigSelects: function(row){
    	thisObj.getRowSelectObjs(row).each(function(select, i){
    		if (select.get('id') != 'pc-type' && select.get('id') != 'env-type')
    			select.set('disabled', true);
    	});
    	
    },
    
    loadConfigSelect: function(row, field, optns){
    	selectObj = thisObj.getRowSelectObj(row, field);
    	selectObj.removeAllOptions();
    	
    	optns.each(function(optn, i){
    		selectObj.addOption(optn.text, optn.value);
    	});
    	
    	
    },
    
    updateEnergyData: function(row) {
    	thisObj.disableConfigSelects(row);
    	
    	pcTypeId 	= thisObj.getPcTypeSelectVal(row);
    	pcTypeDesc 	= thisObj.getPcTypeSelectVal(row, false, true);
    	
    	//get Ajax data
    	var req = thisObj.doJsonReq(row, {
    		'url': 'configenergy/'+pcTypeId,
    		'reqMsg': 'Loading energy data for '+pcTypeDesc+'...',
    		'reqFailMsg': 'Request failed! Please try again.'
    	}, thisObj.getEditPostData(row));
    	
    	if (req.responseFail)
    		return false;
    	
    	data = JSON.decode(req.responseText);
    	
    	DataCells.each(function(cell, i){
    		if (cell == 'btu_hr' || cell == 'kg_co2_yr')
    			row.getElement('td.'+cell+' span').set('text', (data[cell] < 0.01) ? '<0.1' : data[cell]);
    		else
    			row.getElement('td.'+cell+' span').set('text', (data[cell] < 0.01) ? '<0.1' : data[cell].toFixed(2));
    		row.getElement('td.'+cell+' input[type=hidden]').set('value', data[cell]);
    	});
    	
    	thisObj.enableConfigSelects(row);
    	thisObj.clearEditFormResponse(thisObj.getRowId(row));
    	
    	return true;
    },
    
    getEditPostData: function(row){
    	var data = new Hash(); 
    	thisObj.getRowSelectObjs(row).each(function(select, i){
    		data.set(select.get('name'), select.getSelected().get('value'));
    	});
    	
    	data.set('kwh-cost', $('kwh-cost').get('value'));
    	data.set('pc-qty', $('config-edit['+thisObj.getRowId(row)+']').getElement('input[name=pc-qty]').get('value'));
    	return data;
    },
    
    doJsonReq: function(row, config, data) {
    	req = new Request.JSON({
    		url: config.url,
    		async: false,
    		method: 'post',
    		data: data,
    		onRequest: function(){
    			thisObj.showEditFormResponse(thisObj.getRowId(row), config.reqMsg, 'load'); 
    		},
    		onSuccess: function(rObj, rText){ 
    			this.responseText 	= rText;
    			this.responseObj 	= rObj;
    			this.responseFail 	= false;
    		},
    		onFailure: function(){
    			thisObj.showEditFormResponse(thisObj.getRowId(row), config.reqFailMsg, 'error');
    			this.responseFail 	= true;
    		}
    	}).send();
    	return req;
    },
    
    
    //
    
    countDataRows: function(){
    	return thisObj.getDataRows().length;
    },
    
    getDataRows: function(){
    	return $$('#data-table-content tr.config');
    },
    getDataEditRows: function(){
    	return $$('#data-table-content tr.config-edit');
    },
    
    getRowId: function(obj){
    	objId = obj.get('id');
    	return objId.substring(7, (objId.length-1));
    },
    
    getRowIdFromArray: function(key){
    	if(key === 'last') return ConfigIds.getLast();
    	if(key === 'random') return ConfigIds.getRandom();
    	
    	if (ConfigIds[key])
    		return ConfigIds[key]

    	return false;
    },
    
    getRowEditButton: function(obj){
    	return obj.getElement('img.row-edit');
    },
    
    getRowDoneButton: function(obj){
    	return $('config-edit['+thisObj.getRowId(obj)+']').getElement('button.done');
    },
    getRowCancelButton: function(obj){
    	return $('config-edit['+thisObj.getRowId(obj)+']').getElement('button.cancel');
    },
    
    getRowEditLink: function(obj){
    	return obj.getElement('a.row-edit');
    },
    
    getRowDeleteButton: function(obj){
    	return obj.getElement('.row-delete');
    },
    
    getRowSelectObj: function(obj, name){
    	return $('config-edit['+thisObj.getRowId(obj)+']').getElement('select[name='+name+']');
    },
    
    getRowSelectObjs: function(obj){
    	return $('config-edit['+thisObj.getRowId(obj)+']').getElements('select');
    },
    
    getPcTypeSelect: function(obj){
    	return thisObj.getRowSelectObj(obj, 'pc-type');
    },
    
    getEnvTypeSelect: function(obj){
    	return thisObj.getRowSelectObj(obj, 'env-type');
    },
    
    getPcTypeSelectVal: function(obj, override, displayVal){
    	if (override)
    		choice = thisObj.getPcTypeSelect(obj).getElement('option[value='+override+']');
    	else
    		choice = thisObj.getPcTypeSelect(obj).getSelected();

    	if (displayVal)
    		return choice.get('text');
    	return choice.get('value');
    },
    
    getEnvTypeSelectVal: function(obj, override, displayVal){
    	if (override)
    		choice = thisObj.getEnvTypeSelect(obj).getElement('option[value='+override+']');
    	else
    		choice = thisObj.getEnvTypeSelect(obj).getSelected();

    	if (displayVal)
    		return choice.get('text');
    	return choice.get('value');
    },
    
    getRandomRowId: function(){
    	var rowId = $random(random.min, random.max);
    	
    	if (ConfigIds.contains(rowId)) {
    		rowId = thisObj.getRandomRowId()
    	}
    	return rowId;
    },
    
    showEditFormResponse: function(id, msg, cls){    	
    	msgEl = $('config-edit['+id+']').getElement('div[id=edit-form-response]');

    	msgEl.set('text', msg);
    	msgEl.set('class', cls);
    	
    	msgEl.setStyle('display', 'block');
    },
    
    clearEditFormResponse: function(id){
    	msgEl = $('config-edit['+id+']').getElement('div[id=edit-form-response]');
    	
    	msgEl.set('text', '');
    	msgEl.set('class', '');
    	
    	msgEl.setStyle('display', 'none');
    }
});

window.addEvent('domready', function(){
	sysJs = new sysCommon($empty);
});

Element.implement({
	removeAllOptions: function() {
		if(this.get('tag')!='select') return this;
		for(var i=this.options.length-1;i>=1;i--) this.remove(i);
		return this;
	},

	addOption: function(text,value) {
		if(this.get('tag')!='select') return this;
		var optn = new Element('option');
		if(text) optn.text = text;
		if(value) optn.value = value;
		this.options.add(optn);
		return this;
	},

	removeOption: function(prop,value){
		if(this.get('tag')!='select') return this;
		for(var i=this.options.length-1;i>=0;i--) {
			if (prop=='selected' && this.options[i].selected) this.remove(i);
			if (prop=='value' && this.options[i].value==value) this.remove(i);
			if (prop=='text' && this.options[i].text==value) this.remove(i);
			if (prop=='index' && i==value) this.remove(i);
		}
		return this;
	}
});

