/**
 * OSTLUFT - Fachbereich - KanalConfigurationApplication
 *
 * Komponente zur Darstellung und Verwaltung der ausgewählten Kanäle im Fachbereich.
 *
 * Status: Beta
 * Datum: 19.09.2007
 * Autor: Reto Zahner <reto.zahner@asgal.ch>
 */ 
YAHOO.namespace("ostluft.fachbereich");

YAHOO.ostluft.fachbereich.KanalConfigurationApplication = function(htmlElement) {

	if (YAHOO.ostluft.fachbereich.KanalConfigurationApplication._instance)
	{
		return;
	}

	this.pluginPrefix = "tx_ostluft_pi6";

	// HTML-Element welche die GUI der Anwendung enthält
	this.applicationContainer = YAHOO.util.Dom.get(htmlElement ? htmlElement : "kanalConfigurationApplicationContainer");

	// Spaltendefinition der Tabelle
	this.dataTableColumns = [
		{ key:"messstation", label: "Messstation", width:"175px", sortable: true, formatter: YAHOO.ostluft.fachbereich.KanalConfigurationApplication.formatName },
		{ key:"messgroesse", label: "Messgrösse", width:"175px", sortable: true, formatter: YAHOO.ostluft.fachbereich.KanalConfigurationApplication.formatName },
		{ key:"zeitfenster", label: "Zeitfenster", width:"85px", sortable: true, formatter: YAHOO.ostluft.fachbereich.KanalConfigurationApplication.formatName },
		{ key:"einheit", label: "Einheit", width:"50px", sortable: true },
		{ key:"grafik", label: "Diagramm", width:"75px", sortable: true, formatter: YAHOO.ostluft.fachbereich.KanalConfigurationApplication.formatGrafik },
		{ key:"farbe", label: "Farbe", width:"47px", formatter: YAHOO.ostluft.fachbereich.KanalConfigurationApplication.formatFarbe},
		{ key:"kanal_id", label: "Befehle", width:"50px", formatter: YAHOO.ostluft.fachbereich.KanalConfigurationApplication.formatCommandLinks}
	];

	this.dataTableDataSource = null;
	
	// Tabelle für die Kanäle konfigurieren 
	this.dataTable = null

	this.kanalDialogConfiguration =  { 
		visible: false, 
		fixedcenter: true,
		constraintoviewport: true, 
		zindex: 1001,
		width: "400px",
		icon: ".typo3conf/ext/ostluft/resources/table_edit.png"
	};
	
	this.kanalDialogButtons = [ 
		{ text:"Speichern", handler: this.onSubmitKanalDialog, isDefault: true },
		{ text:"Abbrechen", handler: this.onCancelKanalDialog }
	];
	
	// Dialog zur Bearbeitung eines Kanals
	this.kanalDialog = null;
	this.kanalFarbeColorPicker = null;
	
	// Enthält den aktuellen Kanal
	this.currentKanal = null;

	// Liste mit den bereits geladenen Kanälen
	this.kanalDictionary = new Array();
	
	// Liste mit den Konfigurierten Kanälen
	this.kanalConfiguration = new Array();

	// Anwendung initialisieren
	this.init();
	
	// In die Instanzliste eintragen
	YAHOO.ostluft.fachbereich.KanalConfigurationApplication._instance = this;

}; // Ende der Methode: YAHOO.ostluft.fachbereich.KanalConfigurationApplication::KanalConfigurationApplication()

YAHOO.ostluft.fachbereich.KanalConfigurationApplication._instance = null;

YAHOO.ostluft.fachbereich.KanalConfigurationApplication.getInstance = function() {
	
	return YAHOO.ostluft.fachbereich.KanalConfigurationApplication._instance;
	
}; // Ende der Methode: YAHOO.ostluft.fachbereich.KanalConfigurationApplication::onCancelKanalDialog()

YAHOO.ostluft.fachbereich.KanalConfigurationApplication.prototype.init = function() {

	// Datenquelle der Tabelle initialisieren
	this.dataTableDataSource = new YAHOO.util.DataSource(this.kanalDictionary);
	this.dataTableDataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
	this.dataTableDataSource.responseSchema = { fields: ["kanal_id", "messstation", "messgroesse", "zeitfenster", "einheit", "grafik", "farbe", "deleteButton"] };

	this.dataTable = new YAHOO.widget.DataTable(this.applicationContainer, this.dataTableColumns, this.dataTableDataSource);

	this.dataTable.subscribe("linkClickEvent", function(eventObject, targetObject) {
		
		var rowButton = YAHOO.util.Event.getTarget(eventObject);
		var record = this.dataTable.getRecord(rowButton).getData();
		var regex = /([a-z]+)\-([a-z0-9\-]+)/;
		regex.exec(rowButton.id);
		
		switch(RegExp.$1)
		{
			case 'delete':
				this.dataTable.deleteRow(rowButton);
				this.removeKanal(record);
			break;
			case 'edit':
				this.editKanal(record);
			break;
		}
		
		YAHOO.log("Element mit der GUID " + record.kanal_id + " wurde aus der Liste entfernt!", "info", "YAHOO.ostluft.fachbereich.KanalConfigurationApplication::init#buttonClickEvent");
		
	}, this, true);
	
	// Das HTML mit dem Dialog in die oberste Ebende des Body-Tags umhängen
	// Muss gemacht werden, damit der Dialog über den anderen Seitenelementen zu liegen kommt.
	var dialogContainer = YAHOO.util.Dom.get("dialogContainer");
	var dialogContainerClone = dialogContainer.cloneNode(true);
	
	// Bestehendes Element entfernen
	dialogContainer.parentNode.removeChild(dialogContainer);
	
	// Clone in der obersten Ebene anhängen
	document.getElementsByTagName("body")[0].appendChild(dialogContainerClone);
	
	this.kanalDialog = new YAHOO.widget.Dialog("kanalDialog", this.kanalDialogConfiguration);
	this.kanalDialog.cfg.queueProperty("buttons", this.kanalDialogButtons); 
	this.kanalDialog.render();

	// Farbwauswahl 
	this.kanalFarbeColorPicker = new YAHOO.widget.ColorPicker("kanalFarbeColorPicker", {
		images: {
			PICKER_THUMB: "/fileadmin/template/media/yui/colorpicker/assets/picker_thumb.png",
			HUE_THUMB: "/fileadmin/template/media/yui/colorpicker/assets/hue_thumb.png"
		}
	});
	
	this.kanalFarbeColorPicker.on("rgbChange", function(o) {
		var hexColorValue = "#";
		
		for(var i in o.newValue)
		{
			if (typeof o.newValue[i] !== "Function")
			{
				var hexValue = Number(o.newValue[i]).toString(16);
				hexColorValue+= (hexValue.length == 1) ? "0" + hexValue : hexValue
			}
		}
		
		YAHOO.util.Dom.get("kanalFarbe").value = hexColorValue;
	});

	// Nicht benötigt Elemente ausblenden. (Funktioniert nicht über den offiziellen Weg...)	
	YAHOO.util.Dom.setStyle(["yui-picker-swatch", "yui-picker-websafe-swatch", "yui-picker-controls"], "display", "none");
	
	YAHOO.util.Event.addListener("kanalGrafik", "change", function(e) {
		var target = YAHOO.util.Event.getTarget(e);
		switch(target.options[target.selectedIndex].value)
		{
			case "-":
				YAHOO.util.Dom.get("kanalYSkala").selectedIndex = 0;
				break;
				
			case "Windgrafik":
				YAHOO.util.Dom.get("kanalYSkala").selectedIndex = 0;
				break;
				
			default:
			
				var recordset = this.dataTable.getRecordSet();
				var grafikCount = 0;
				for(var i = 0, l = recordset.getLength(); i < l; i++)
				{
					var record = recordset.getRecord(parseInt(i));
					if (record)
					{
						var grafik = record.getData("grafik");
						if (grafik != "-")
						{
							grafikCount+= 1;
						}
					}
				}
			
				if (grafikCount >= 6)
				{
					alert("Es wurden bereits 6 Kanäle der Grafik zugewiesen. Sie können keine weiteren Kanäle einer Grafik zuweisen.");
					target.selectedIndex = 0;
				}
				else
				{
					YAHOO.util.Dom.get("kanalYSkala").selectedIndex = 1;
				}
				break;
		}
	}, this, true);
	
	YAHOO.log("Modul initialisiert!", "info", "YAHOO.ostluft.fachbereich.KanalConfigurationApplication::init");

} // Ende der Methode: YAHOO.ostluft.fachbereich.KanalConfigurationApplication::KanalConfigurationApplication()

YAHOO.ostluft.fachbereich.KanalConfigurationApplication.prototype.getKanal = function() {
	
	return this.currentKanal;
	
} // Ende der Methode: YAHOO.ostluft.fachbereich.KanalConfigurationApplication::getCurrentKanal()

YAHOO.ostluft.fachbereich.KanalConfigurationApplication.prototype.beginEditKanal = function(kanal) {
	
	this.currentKanal = kanal;
	
} // Ende der Methode: YAHOO.ostluft.fachbereich.KanalConfigurationApplication::setCurrentKanal()

YAHOO.ostluft.fachbereich.KanalConfigurationApplication.prototype.endEditKanal = function() {
	
	this.currentKanal = null;
	
} // Ende der Methode: YAHOO.ostluft.fachbereich.KanalConfigurationApplication::cancelCurrentKanal()

YAHOO.ostluft.fachbereich.KanalConfigurationApplication.prototype.updateKanal = function(kanal) {
	
	this.kanalConfiguration[kanal.kanal_id] = kanal;
	
	// Todo: Update DataTable
	var recordset = this.dataTable.getRecordSet();
	
	for(var i = 0; i < recordset.getLength(); i++)
	{
		var record = recordset.getRecord(i);
		if (record.getData().kanal_id == kanal.kanal_id)
		{
			this.dataTable.updateRow(i, kanal);
		}
	}
	
} // Ende der Methode: YAHOO.ostluft.fachbereich.KanalConfigurationApplication::cancelCurrentKanal()

YAHOO.ostluft.fachbereich.KanalConfigurationApplication.prototype.addKanal = function(kanal, isRow) {

	if (!kanal.kanal_id)
	{
		YAHOO.log("Sie versuchen einen ungültigen Kanal hinzuzufügen!", "error", "YAHOO.ostluft.fachbereich.KanalConfigurationApplication::KanalConfigurationApplication");
		throw "Sie versuchen einen ungültigen Kanal hinzuzufügen!";
	}

	if (this.kanalDictionary[kanal.kanal_id])
	{
		YAHOO.log("Der Kanal mit der GUID " + kanal.kanal_id + " ist bereits in der Liste vorhanden!", "info", "YAHOO.ostluft.fachbereich.KanalConfigurationApplication::KanalConfigurationApplication");
		return false;
	}
	
	var kanalRow = kanal;
	
	if (isRow != true)
	{
		var kanalCount = parseInt(this.dataTable.getRecordSet().getLength());
		
		if (kanalCount < 3)
		{
			kanalRow.grafik = 0;
			kanalRow.yskala = "Links";
		}
		else if (kanalCount < 6)
		{
			kanalRow.grafik = 1;
			kanalRow.yskala = "Links";
		}
		else
		{
			kanalRow.grafik = "-";
			kanalRow.yskala = "-";
		}
		
		// Farbwert konvertieren
		var rgbValue = this.convertHSV2RGB({ 
			h:(kanalCount*(1/5.143))%1, 
			s:1, 
			v:0.75 
		});
		
		// Farbwerte in Hex-Strings konvertieren und auf zwei Zeichen Länge bringen.
		var rString = rgbValue.r.toString(16);
		if (rString.length == 1)
		{
			rString = "0" + rString;
		} 
		
		var gString = rgbValue.g.toString(16);
		if (gString.length == 1)
		{
			gString = "0" + gString;
		} 
		
		var bString = rgbValue.b.toString(16);
		if (bString.length == 1)
		{
			bString = "0" + bString;
		} 
		
		// Farbwert zsuammensetzen und zuweisen
		kanalRow.farbe = "#" + rString + gString + bString;;
		kanalRow.symbol = "-";
		kanalRow.diagramm = "line";
		kanalRow.breite = "1";
	}
	
	this.kanalDictionary[kanal.kanal_id] = kanal;
	this.kanalConfiguration[kanal.kanal_id] = kanalRow;

	this.dataTable.addRow(kanalRow);
	
	return true;

} // Ende der Methode: YAHOO.ostluft.fachbereich.KanalConfigurationApplication::KanalConfigurationApplication()

YAHOO.ostluft.fachbereich.KanalConfigurationApplication.prototype.removeKanal = function(kanal) {

	if (!kanal.kanal_id)
	{
		YAHOO.log("Sie haben versucht einen ungültigen Kanal zu löschen!", "error", "YAHOO.ostluft.fachbereich.KanalConfigurationApplication::KanalConfigurationApplication");
		throw "Sie haben versucht einen ungültigen Kanal zu löschen!";
	}

	if (!this.kanalDictionary[kanal.kanal_id])
	{
		YAHOO.log("Der Kanal mit der GUID " + kanal.kanal_id + " ist nicht in der Liste vorhanden!", "info", "YAHOO.ostluft.fachbereich.KanalConfigurationApplication::KanalConfigurationApplication");
		return false;
	}
	
	//if (confirm("Bestätigen Sie bitte mit OK, dass sie den Kanal aus der Liste löschen möchten!"))
	if(true)
	{
		this.kanalDictionary[kanal.kanal_id] = null;
		this.kanalConfiguration[kanal.kanal_id] = null;
		
		return true;
	}
	else
	{
		return false;
	}

} // Ende der Methode: YAHOO.ostluft.fachbereich.KanalConfigurationApplication::KanalConfigurationApplication()

/**
 * Stellt den Kanal-Dialog dar und füllt ihn mit den entsprechenden Daten aus dem Kanal
 */
YAHOO.ostluft.fachbereich.KanalConfigurationApplication.prototype.editKanal = function(kanal) {
	
	// Informationsspalten (Können nicht verändert werden)
	YAHOO.util.Dom.get("kanalMessstation").value = kanal.messstation;
	YAHOO.util.Dom.get("kanalMessgroesse").value = kanal.messgroesse;
	YAHOO.util.Dom.get("kanalZeitfenster").value = kanal.zeitfenster;
	YAHOO.util.Dom.get("kanalEinheit").value = kanal.einheit;
	YAHOO.util.Dom.get("kanalGrafik").value = kanal.grafik;
	YAHOO.util.Dom.get("kanalFarbe").value = kanal.farbe;
	YAHOO.util.Dom.get("kanalYSkala").value = kanal.yskala;
	YAHOO.util.Dom.get("kanalSymbol").value = kanal.symbol;
	
	this.beginEditKanal(kanal);
	
	// IE6 Hack: Select Elemente ausblenden
	YAHOO.ASGAL.IE6HackUtility.hideSelectBoxes(true);
	
	if (this.kanalFarbeColorPicker)
	{
		var hexColorValue = YAHOO.util.Dom.get("kanalFarbe").value;
		if ((hexColorValue.substr(0,1) === "#") && (hexColorValue.length == 7))
		{
			this.kanalFarbeColorPicker.setValue([
				parseInt(hexColorValue.substr(1, 2), 16),
				parseInt(hexColorValue.substr(3, 2), 16),
				parseInt(hexColorValue.substr(5, 2), 16)
			], false);
		}
	}
	
	this.kanalDialog.show();
	
} // Ende der Methode: YAHOO.ostluft.fachbereich.KanalConfigurationApplication::editKanal()

/**
 * Wird aufgerufen wenn der Dialog gespeichert wird.
 * Scope: Dialog
 */
YAHOO.ostluft.fachbereich.KanalConfigurationApplication.prototype.onSubmitKanalDialog = function() {
	
	var kanalConfigurationApplication = YAHOO.ostluft.fachbereich.KanalConfigurationApplication.getInstance();
	var kanal = kanalConfigurationApplication.getKanal();
	
	kanal.einheit = YAHOO.util.Dom.get("kanalEinheit").value;
	kanal.grafik = YAHOO.util.Dom.get("kanalGrafik").value;
	kanal.farbe = YAHOO.util.Dom.get("kanalFarbe").value;
	kanal.yskala = YAHOO.util.Dom.get("kanalYSkala").value;
	kanal.symbol = YAHOO.util.Dom.get("kanalSymbol").value;
	
	kanalConfigurationApplication.updateKanal(kanal);
	kanalConfigurationApplication.endEditKanal();
	
	// IE6 Hack: Select Elemente einblenden
	YAHOO.ASGAL.IE6HackUtility.hideSelectBoxes(false);
	
	// Kein Submit! Nur die Daten in Record schreiben und schliessen!
	this.cancel();
	
} // Ende der Methode: YAHOO.ostluft.fachbereich.KanalConfigurationApplication::onSubmitKanalDialog()

/**
 * Wird aufgerufen wenn der Dialog abgebrochen wird.
 * Scope: Dialog
 */
YAHOO.ostluft.fachbereich.KanalConfigurationApplication.prototype.onCancelKanalDialog = function() {
	
	var kanalConfigurationApplication = YAHOO.ostluft.fachbereich.KanalConfigurationApplication.getInstance();
	kanalConfigurationApplication.endEditKanal();
	
	// IE6 Hack: Select Elemente einblenden
	YAHOO.ASGAL.IE6HackUtility.hideSelectBoxes(false);
	
	// Abbruch...
	this.cancel();
	
} // Ende der Methode: YAHOO.ostluft.fachbereich.KanalConfigurationApplication::onCancelKanalDialog()

/**
 * Gibt die Liste der konfigurierten Kanäle zurück.
 *
 * Die Liste entspricht einem assoziativen Array (Hashmap)
 */
YAHOO.ostluft.fachbereich.KanalConfigurationApplication.prototype.getKanalList = function() {
	
	return this.kanalConfiguration;
	
} // Ende der Methode: YAHOO.ostluft.fachbereich.KanalConfigurationApplication::getKanalList()

YAHOO.ostluft.fachbereich.KanalConfigurationApplication.prototype.deleteKanal = function(kanal) {
	
	// Datensatz und Index des Kanals ermitteln
	var oRecord = this.findRecord(this.dataTable, "kanal_id", kanal.kanal_id);
	var recordIndex = parseInt(this.dataTable.getRecordSet().getRecordIndex(oRecord));

	// Kanal aus der Tabelle entfernen
	this.dataTable.deleteRow(recordIndex);
	this.dataTable.refreshView();
	
	// Kanal aus den internen Datenstrukturen löschen
	this.removeKanal(kanal);
	
} // Ende der Methode: YAHOO.ostluft.fachbereich.KanalConfigurationApplication::getKanalList()

/**
 * Formatiert einen Name auf eine feste Anzahl Zeichen.
 */
YAHOO.ostluft.fachbereich.KanalConfigurationApplication.formatName = function (elCell, oRecord, oColumn, oData)
{ 
	var maxLength = 30;
	var nameNode = null;
	if (oData.length > maxLength)
	{
		nameNode = document.createElement("span");
		nameNode.title = oData;
		nameNode.appendChild(document.createTextNode(oData.substr(0, maxLength) + "..."));
	}
	else
	{
		nameNode = document.createTextNode(oData);
	}
	
	elCell.innerHTML = "";
	elCell.appendChild(nameNode);
}

YAHOO.ostluft.fachbereich.KanalConfigurationApplication.formatGrafik = function (elCell, oRecord, oColumn, oData)
{ 
	if (oData == "-")
	{
		elCell.innerHTML = oData;
	}
	else
	{
		elCell.innerHTML = "Diagramm " + (parseInt(oData) + 1);
	}
}

/**
 * Formatiert einen Name auf eine feste Anzahl Zeichen.
 */
YAHOO.ostluft.fachbereich.KanalConfigurationApplication.formatFarbe = function(elCell, oRecord, oColumn, oData)
{ 
	var colorNode = document.createElement("div");
	colorNode.title = oData;
	YAHOO.util.Dom.addClass(colorNode, "farbe");
	YAHOO.util.Dom.setStyle(colorNode, "color", oData);
	colorNode.appendChild(document.createTextNode(oData));
	
	elCell.innerHTML = "";
	elCell.appendChild(colorNode);
}

YAHOO.ostluft.fachbereich.KanalConfigurationApplication.formatCommandLinks = function(elCell, oRecord, oColumn, oData) {

	var oRecordData = oRecord.getData();
	
	var innerHTML = "<a href=\"javascript:;\" id=\"edit-" + oRecordData.kanal_id + "\" title=\"Kanal bearbeiten\" class=\"icon edit\"><img src=\"typo3conf/ext/ostluft/resources/table_edit.png\" alt=\"bearbeiten\" class=\"icon edit\"/></a>";
	innerHTML+= "<a href=\"javascript:;\" id=\"delete-" + oRecordData.kanal_id + "\" title=\"Kanal entfernen\" class=\"icon delete\"><img src=\"typo3conf/ext/ostluft/resources/table_delete.png\" alt=\"entfernen\" class=\"icon delete\"/></a>";
	
    elCell.innerHTML = innerHTML;
   
};

/**
 * Methode zur Konvertierung von HSV nach RGB.
 *
 * Diese Methode wird benötigt um die automatische Berechnung der Farbwerte für die 1. sechs 
 * Kanäle zu gewährleisten.
 *
 * Es wird ein HSV-Objekt mit den Elementen h,s,v übergeben 
 * und ein Objekt mit den Elementen r,g,b zurückgegeben. 
 */
YAHOO.ostluft.fachbereich.KanalConfigurationApplication.prototype.convertHSV2RGB = function(hsvValue) {

	var rgbValue = {r:0, g:0, b:0};

	if (hsvValue.s == 0)
	{
		//HSV values = 0 ÷ 1
	   rgbValue.r = Math.floor(hsvValue.v * 255);
	   rgbValue.g = Math.floor(hsvValue.v * 255);
	   rgbValue.b = Math.floor(hsvValue.v * 255);
	}
	else
	{
		var h = hsvValue.h * 6;
		if (h == 6) 
		{
			h=0;
		}
		
		//Or ... var_i = floor( var_h )
		var i = Math.floor(h);
		var i1 = hsvValue.v * (1 - hsvValue.s);
		var i2 = hsvValue.v * (1 - hsvValue.s * (h - i));
		var i3 = hsvValue.v * (1 - hsvValue.s * (1 - (h - i)));
	
		if (i == 0) 
		{ 
			var r = hsvValue.v;
			var g = i3;
			var b = i1;
		}
		else if (i == 1) 
		{ 
			var r = i2;
			var g = hsvValue.v;
			var b = i1;
		}
		else if (i == 2) 
		{
			var r = i1;
			var g = hsvValue.v;
			var b = i3;
		}
		else if (i == 3) 
		{ 
			var r = i1; 
			var g = i2; 
			var b = hsvValue.v;
		}
		else if (i == 4) 
		{ 
			var r = i3; 
			var g = i1; 
			var b = hsvValue.v;
		}
		else
		{
			var r = hsvValue.v;
			var g = i1;
			var b = i2;
		}
	
		//RGB results = 0 ÷ 255
		rgbValue.r = Math.floor(r * 255);                 
		rgbValue.g = Math.floor(g * 255);
		rgbValue.b = Math.floor(b * 255);
	}
	
	return rgbValue;
	
} // Ende der Methode: YAHOO.ostluft.fachbereich.KanalConfigurationApplication.prototype.convertHSV2RGB()

/**
 * Gibt die ausgewählte Zeile oder null zurück.
 *
 * @public
 *
 * @return	{YAHOO.widget.Record}
 */
YAHOO.ostluft.fachbereich.KanalConfigurationApplication.prototype.findRecord = function(datatable, key, value) {

	var recordSet = datatable.getRecordSet();
	var lm = recordSet.getLength(); // 0 bis recordCount-1
	var lhu = parseInt(Math.ceil(lm/2));
	var lhl = lm - lhu;
	
	for(i=0; i<lhu; i++) {
		var record = recordSet.getRecord(i);
		if (record.getData(key) == value) {
			return record;
		}
		if (i+lhl < lm) {
			record = recordSet.getRecord(i+lhl);
			if (record.getData(key) == value) {
				return record;
			}
		}
	}
	
	return null;
	
} // Ende der Methode: findRecord()
