/** 
* Copyright 2006-2008 massimocorner.com
* @author      Massimo Foti (massimo@massimocorner.com)
* @version     2.0.0, 2008-05-20
* @require     tmt_core.js
*/

if(typeof(tmt) == "undefined"){
	alert("Error: tmt.core JavaScript library missing");
}

if(typeof(tmt.widget) == "undefined"){
	tmt.widget = {};
}

tmt.widget.expandpanel = {};

tmt.widget.expandpanel.ERRMSG_WRONG_XHTML = "Error: tmt.widget.expandpanel requires a very specific structure for XHTML tags";
tmt.widget.expandpanel.ERROR_CLASS = "tmtPanelError";

tmt.widget.expandpanel.containerFactory = function(rootNode){
	var obj = {};
	obj.rootNode = rootNode;
	obj.currentPosition = 0;
	obj.panels = [];
	obj.insideForm = false;
	obj.formNode = null;
	if(obj.rootNode.getAttribute("tmt:expandpanelform")){
		if(typeof(tmt.validator) == "undefined"){
			alert("Error: TMT Validator JavaScript library missing");
		}
		obj.insideForm = true;
		obj.formNode = tmt.form.getParentForm(obj.rootNode);
	}

	// Returns already visited panel objects
	obj.getVisitedPanels = function(){
		var retPanels = [];
		for(var i=0; i<obj.panels.length; i++){	
			if(obj.panels[i].isVisited()){
				retPanels.push(obj.panels[i]);
			}
		}
		return retPanels;
	}

	// Returns true if we have to validate form fields whenever we switch panel
	obj.hasForm = function(){
		return (obj.insideForm && obj.formNode);
	}

	obj.getValidationCallback = function(){
		if(obj.rootNode.getAttribute("tmt:expandpanelformcallback")){
			return obj.rootNode.getAttribute("tmt:expandpanelformcallback");
		}
		return tmt.validator.DEFAULT_CALLBACK_MULTISECTION;
	}

	obj.openPanel = function(position){
		for(var j=0; j<obj.panels.length; j++){
			obj.panels[j].hide();
		}
		// Open panel only if it's inside the range
		if((position >= 0) && (position <= obj.panels.length)){
			// Flag previous panel as visited
			obj.panels[obj.currentPosition].setVisited()
			obj.panels[position].show();
			obj.validate();
			obj.currentPosition = position;
		}
	}

	// Validate form fields inside already visited panels
	obj.validate = function(all){
		var panels = obj.getVisitedPanels();
		if(all){
			panels = obj.panels;
		}
		if(obj.hasForm()){
			var results = obj.validatePanels(panels);
			var callback = obj.getValidationCallback();
			// Forward results to the callback
			eval(callback + "(obj.formNode, results.hasErrors, results.sectionResults)");
			return results.hasErrors == false;
		}
		return true;
	}

	// Validate form fields inside all tabs
	obj.validateAll = function(){
		return obj.validate(true);
	}

	// Validate panels, returns a results object
	obj.validatePanels = function(panels){
		var sectionResults = [];
		var hasErrors = false;
		for(var i=0; i<panels.length; i++){
			var panelResults = {};
			panelResults.label = panels[i].name;
			panelResults.validators = [];
			var validators = panels[i].getValidators();
			var activeValidators = tmt.validator.executeValidators(validators);
			// If errors, attach active validators
			if(activeValidators.length > 0){
				panelResults.validators = activeValidators;
				panels[i].flagInvalid();
				hasErrors = true;
			}
			else{
				panels[i].flagValid();
			}
			sectionResults.push(panelResults);
		}
		return {sectionResults: sectionResults, hasErrors: hasErrors};
	}

	// Identify all childern <div> nodes and turn them into panel objects
	for(var i=0; i<obj.rootNode.childNodes.length; i++){
		if(obj.rootNode.childNodes[i].tagName && obj.rootNode.childNodes[i].tagName.toLowerCase() == "div"){
			var childPanel = tmt.widget.expandpanel.panelFactory(obj, obj.rootNode.childNodes[i], obj.panels.length);
			obj.panels.push(childPanel);
		}
	}
	return obj;
}

tmt.widget.expandpanel.panelFactory = function(containerObj, rootNode, position){
	var obj = {};
	obj.container = containerObj;
	obj.rootNode = rootNode;
	obj.position = position;
	obj.labelNode = obj.rootNode.getElementsByTagName("a")[0];
	obj.name = obj.labelNode.innerHTML;
	obj.visited = false;

	if(!obj.labelNode){
		alert(tmt.widget.expandpanel.ERRMSG_WRONG_XHTML);
		return false;
	}
	obj.contentNode = obj.rootNode.getElementsByTagName("div")[0];
	if(!obj.contentNode){
		alert(tmt.widget.expandpanel.ERRMSG_WRONG_XHTML);
		return false;
	}

	obj.getValidators = function(){
		var fields = tmt.form.getChildFields(obj.rootNode);
		var validators = [];
		for(var i=0; i<fields.length; i++){
			validators.push(tmt.validator.fieldValidatorFactory(fields[i]));
		}
		return validators;
	}

	obj.flagInvalid = function(){
		tmt.addClass(obj.labelNode, tmt.widget.expandpanel.ERROR_CLASS);
	}

	obj.flagValid = function(){
		tmt.removeClass(obj.labelNode, tmt.widget.expandpanel.ERROR_CLASS);
	}

	obj.hide = function(){
		obj.contentNode.style.display = "none";
	}

	obj.isVisited = function(){
		return obj.visited;
	}

	obj.setVisited = function(){
		obj.visited = true;
	}

	obj.show = function(){
		obj.contentNode.style.display = "block";
	}	

	obj.clickHandler = function(){
		obj.container.openPanel(obj.position);
	}

	tmt.addEvent(obj.labelNode, "click", obj.clickHandler);
	return obj;
}

tmt.widget.expandpanel.init = function(){
	var divNodes = document.getElementsByTagName("div");
	var panelNodes = tmt.filterNodesByAttributeValue("tmt:expandpanel", "true", divNodes);
	for(var i=0; i<panelNodes.length; i++){
		panelNodes[i].tmtExpandpanelContainer = tmt.widget.expandpanel.containerFactory(panelNodes[i]);
	}
}

// Global object storing utility methods
tmt.widget.expandpanel.util = {};

// Private method. Given a <div> node or its id, return its expandpanel object
tmt.widget.expandpanel.util.getObjFromNode = function(containerNode){
	var targetNode = tmt.get(containerNode);
	if(!targetNode){
		alert("Error: unable to find the requested expandpanel");
		return null;
	}
	var targetObj = targetNode.tmtExpandpanelContainer;
	if(!targetObj){
		alert("Error: the request element is not an expandpanel. Verify it contains the tmt:expandpanel attribute");
		return null;
	}
	return targetObj;
}

/**
* Given a <div> node or its id, open the required panel (panel position is zero based)
*/
tmt.widget.expandpanel.util.openPanel = function(containerNode, position){
	var expandContainer = tmt.widget.expandpanel.util.getObjFromNode(containerNode);
	if(expandContainer){
		expandContainer.openPanel(position);
	}
}

/**
* Given a <div> node or its id, validate form fields inside all panels
*/
tmt.widget.expandpanel.util.validate = function(containerNode){
	var expandContainer = tmt.widget.expandpanel.util.getObjFromNode(containerNode);
	return expandContainer.validateAll();
}

tmt.addEvent(window, "load", tmt.widget.expandpanel.init);
