/**
 * AINS Corporate Pricing Widget
 * 
 * @author bart Lea
 * @version 0.1
 */

var AINS = {};
AINS.Corporate = {};

/**
 * This class provides the interface for the AINS corporate website price 
 * calculator.
 */
AINS.Corporate.serviceManager = function(nodes, displayNodes) {
	
	/**
	 * Instance vars
	 */
	var SELF = this;
	this.childClassType = "Service";
	this.nodes = nodes;
	this.displayNodes = displayNodes;
	this.selectNodes = {};
	this.debugOn = true;
	
	
	/**
	 * Basic initialiser 
	 * @constructor
	 */		
	this.init = function(services, selectedService) {
		
		SELF.data = services;
		SELF.childData = [];
		
		for(var node in SELF.nodes){
			SELF.selectNodes[node] = null
		}
		
		for(var i = 0; i < SELF.data.length; i++) {
			SELF.childData.push(new AINS.Corporate.Service(SELF, SELF.data[i]));
		}
		SELF.updateChildren();
		
		if(selectedService) {
			SELF.selectService(selectedService);
		}
		
	}
	
	
	/**
	 * Allows a particular service to be selected by value
	 */
	this.selectService = function(selectedService) {
		
		//enable service selection
		if(selectedService) {
			SELF.setSelectedOptionByValue(SELF.getNode("Service"), selectedService);
			SELF.getSelectedChild();
		}
		
	}
	
	
	/**
	 * Allows debugging to be enabled/disabled
	 */	
	this.enableDebug = function(debugOn){
		SELF.debugOn = debugOn;
	}
	
	
	/**
	 * Displays debug output
	 */	
	this.debugOut = function(text){
		
		var debugArea = $("debugOut");
		if(SELF.debugOn && debugArea) {
			debugArea.value = text + "\n" + debugArea.value;
		}
	}
	
	
	/**
	 * appends node information to array.
	 */
	this.nodeSelected = function(nodeType, node) {
		
		//SELF.debugOut("Node Selected: " + nodeType + ", " + node.toString());
		
		//save the current selections before the update
		
		
    	SELF.selectNodes[nodeType] = node;
    	SELF.updateDisplay();
	}	
	
	
	/**
	 * gets selected node information to array.
	 */
	this.getNodeSelected = function(nodeType) {
		
		
		var selectedNode = SELF.selectNodes[nodeType];
		
		
    	return selectedNode;
	}
	
	/**
	 * Gets Select Box Node's From Page. 
	 */
	this.getNode = function(nodeName) {
		try{
			return $(SELF.nodes[nodeName]);
			
		} catch(e) {
			alert("Error:" + e.toString());
			return null;
		}
	}
	
	
	/**
	 * Gets Nodes for Information Display.
	 */	
	this.getDisplayNode = function(nodeName) {
		try{
			return $(SELF.displayNodes[nodeName]);
			
		} catch(e) {
			alert("Error:" + e.toString());
			return null;
		}
	}
	
	
	/**
	 * collects information from children and displays on page
	 */
	this.updateDisplay = function() {
		
		var newDisplayValues = {price:0, installation:0, description:"", warning:""};
		
		try{
			for(var node in SELF.selectNodes){
				var currentNode = SELF.selectNodes[node];
				newDisplayValues.price += currentNode.getPrice();
				newDisplayValues.installation += currentNode.getInstallation();
				newDisplayValues.description += currentNode.getDescription();
				newDisplayValues.warning += currentNode.getWarning();
			}
		
		} catch(e){
			
		}
			
		var priceNode = SELF.getDisplayNode("Price");
		var installationNode = SELF.getDisplayNode("Installation");
		var descriptionNode = SELF.getDisplayNode("Description");
		var warningNode = SELF.getDisplayNode("Warning");
		
		priceNode.value = SELF.getPriceString(newDisplayValues.price);
		installationNode.value = SELF.getPriceString(newDisplayValues.installation);
		descriptionNode.innerHTML = newDisplayValues.description;
		warningNode.innerHTML = newDisplayValues.warning;
	}
	
	
	/**
	 * rounds off price after decimal for display.
	 */
	this.getPriceString = function(price) {
		
		var prices = {};
		prices.times100 = price * 100;
		prices.rounded = Math.round(prices.times100);
		prices.normalised = prices.rounded / 100;
		
		if(prices.normalised.toFixed) {
			prices.normalised = new String(prices.normalised.toFixed(2));
		} else {
			prices.normalised = new String(prices.normalised);
		}
		
		return prices.normalised;
	}
	
	
	/**
	 * Appends infromation to Child(Services).
	 */
	this.updateChildren = function() {
		
		var serviceDomNode = SELF.getNode("Service");
		serviceDomNode.onchange = SELF.getSelectedChild;
		serviceDomNode.innerHTML = "";
		
		for(var i = 0; i < SELF.childData.length; i++) {
			var newServiceNode = SELF.childData[i].getDomNode();
			serviceDomNode.appendChild(newServiceNode);
		}
		SELF.childData[0].updateChildren();
		
	}
	
	
	/**
	 * General method to find a selected value from a select dom node
	 */
	this.getSelectedOption = function(selectNode) {
		var select = $(selectNode);
		for(var i = 0; select && i < select.options.length; i++) {
			if(select.options[i].selected) {
				return select.options[i];
			}
		}
		return null;
	}
	
	
	/**
	 * General method to select an option by value
	 */
	this.setSelectedOptionByValue = function(selectNode, optionValue) {
		var select = $(selectNode);
		for(var i = 0; i < select.options.length; i++) {
			if(select.options[i].value == optionValue) {
				select.options[i].selected = true;
				return select.options[i];
			}
		}
		return null;
	}
	
	
	/**
	 * This method finds the selected child node and updates the calculator.
	 */
	this.getSelectedChild = function() {
		
		var selectedOption = SELF.getSelectedOption( SELF.getNode(SELF.childClassType) );
		for(var i = 0; i < SELF.childData.length; i++) {
			if(selectedOption.value == SELF.childData[i].data.TITLE) {
				SELF.childData[i].updateChildren();
			}
		}
	}
	
	
};


/**
 * This class models a service for AINS corporate website (price calculator)
 */
AINS.Corporate.Service = function(serviceManager, data) {
	
	var SELF = this;
	this.classType = "Service";
	this.childClassType = "Contract";
	this.serviceManager = serviceManager;

	/**
	 * basic initialiser 
	 * @constructor
	 */	
	 
	this.init = function(data) {
		
		SELF.data = data;
		SELF.childData = [];
		
		for(var i = 0; i < SELF.data.CONTRACTS.length; i++) {
			SELF.childData.push(new AINS.Corporate.Contract(SELF.serviceManager, SELF.data.CONTRACTS[i]));
		}
		SELF.updateChildren();
	}

	/**
	 * 	Sends selected Node To service manager.
	 */
	 
	this.nodeSelected = function(){
		
		SELF.serviceManager.nodeSelected(SELF.classType, SELF);
	}

	/**
	 * When Called below send Node Values to service manager.
	 */
		
	this.getInstallation = function() { 
			
		return 0; 
	} 
	
	this.getPrice = function() {
			
		return 0;
	}
	
	this.getDescription = function() {	
		
		var returnedDescription = "A " + SELF.data.DESCRIPTION;
		
		return returnedDescription;
	}
	
	this.getWarning = function() {	
		
		return SELF.data.WARNING;
	}

	/**
	 * Sets Atributes for child before appended in Update Children.
	 */ 
	this.getDomNode = function() {
		
		var serviceNode = document.createElement("option");
		serviceNode.setAttribute("value", SELF.data.TITLE);
		serviceNode.setAttribute("title", SELF.data.DESCRIPTION);
		
		var serviceNodeText = document.createTextNode(SELF.data.TITLE);
		serviceNode.appendChild(serviceNodeText);
		
		return serviceNode;
	}

	/**
	 * Appends infromation to Child(Contracts).
	 */
	this.updateChildren = function() {		
		
		var contractDomNode = SELF.serviceManager.getNode(SELF.childClassType);
		contractDomNode.onchange = SELF.getSelectedChild;
		contractDomNode.innerHTML = "";
		
		for(var i = 0; i < SELF.childData.length; i++) {
			var newContractNode = SELF.childData[i].getDomNode();
			contractDomNode.appendChild(newContractNode);
		}
		SELF.childData[0].updateChildren();
		SELF.nodeSelected();
	}
	
	/**
	 * Sets selected in child, and self.
	 */
	 
	this.setSelected = function(){
		
		SELF.childData[0].nodeSelected();
		SELF.nodeSelected();			
	}	
	
	/**
	 * Checks Value of Combo against Array.
	 */ 
	this.getSelectedChild = function() {
		
		SELF.serviceManager.debugOut("Service Child (Contract) Selected");
		
		var selectedOption = SELF.serviceManager.getSelectedOption( SELF.serviceManager.getNode(SELF.childClassType) );
		for(var i = 0; i < SELF.childData.length; i++) {
			if(selectedOption.value == SELF.childData[i].data.TITLE) {
				SELF.childData[i].updateChildren();
			}
		}
	}
	SELF.init(data);
};

AINS.Corporate.Contract = function(serviceManager, data, domNode) {
	
	var SELF = this;
	this.classType = "Contract";
	this.childClassType = "contractOptions";
	this.data = data;
	this.serviceManager = serviceManager;

	/**
	 * basic initialiser 
	 * @constructor
	 */	
	 
	this.init = function(data) {
		
		SELF.data = data;
		SELF.childData = [];
		
		for(var i = 0; i < SELF.data.CONTRACTOPTIONS.length; i++) {
			SELF.childData.push(new AINS.Corporate.contractOptions(SELF.serviceManager, SELF.data.CONTRACTOPTIONS[i]));
		}
		
		SELF.updateChildren();		
	}

	/**
	 * Sends selected Node To service manager.
	 */
		
	this.nodeSelected = function(){
		
		//debug
		//SELF.serviceManager.debugOut("Node Selected: " + SELF.classType + ", " + SELF.data.TITLE);
		SELF.serviceManager.debugOut("Node Selected: " + SELF.classType);
		
		SELF.serviceManager.nodeSelected(SELF.classType, SELF);
	}
	
	/**
	 * When Called below send Node Values to service manager.
	 */
		
	this.getInstallation = function() { 
			
		return 0; 
	} 
	
	this.getPrice = function() {
			
		return 0;
	}
	
	this.getDescription = function() {	

		var returnedDescription = "";
		
		if(SELF.data.TITLE == "No Contract"){
			
			returnedDescription = ", with " + SELF.data.DESCRIPTION;
		} else {
			
			returnedDescription = ", with a " + SELF.data.DESCRIPTION;
		}
		
		return returnedDescription;
	}
	
	this.getWarning = function() {	
		
		return SELF.data.WARNING;
	}

	/**
	 * Sets Atributes for child before appended in Update Children.
	 */
	 	
	this.getDomNode = function() {
		
		var serviceNode = document.createElement("option");
		serviceNode.setAttribute("value", SELF.data.TITLE);
		serviceNode.setAttribute("title", SELF.data.DESCRIPTION);
				
		var serviceNodeText = document.createTextNode(SELF.data.TITLE);
		serviceNode.appendChild(serviceNodeText);
		
		return serviceNode;
	}
	
	/**
	 * Appends infromation to Child(Contract Options).
	 */
	
	this.updateChildren = function() {
		
		
		var selectedChild = SELF.serviceManager.getNodeSelected(SELF.childClassType);
		var selectedChildOption = 0;
		SELF.serviceManager.debugOut(SELF.classType + ".updateChildren() " + selectedChild.data.TITLE );
		
		var contractOptionsDomNode = SELF.serviceManager.getNode(SELF.childClassType);
		contractOptionsDomNode.onchange = SELF.getSelectedChild;
		contractOptionsDomNode.innerHTML = "";
		for(var i = 0; i < SELF.childData.length; i++) {
			
			if( SELF.childData[i].data.TITLE == selectedChild.data.TITLE ) {
				selectedChildOption = i;
				SELF.childData[i].setSelected();
				contractOptionsDomNode.setAttribute("selected", true);
			}
			
			var newcontractOptionsNode = SELF.childData[i].getDomNode();
			contractOptionsDomNode.appendChild(newcontractOptionsNode);
			
		}
		
		//set the selected value
		SELF.serviceManager.setSelectedOptionByValue(
			SELF.serviceManager.getNode(SELF.childClassType), 
			selectedChild.data.TITLE
		)
		
		
		SELF.childData[selectedChildOption].updateChildren();
		SELF.nodeSelected();
		
		
		return;
	}
	
	/**
	 * Sets selected in child, and self.
	 */ 
	this.setSelected = function(){
		
		SELF.childData[0].nodeSelected();
		SELF.nodeSelected();
	}
	
	/**
	 * Checks Value of Combo against Array.
	 */ 
	this.getSelectedChild = function() {
		
		//get selected child
		//var selectedChildOption = SELF.serviceManager.getSelectedOption( SELF.serviceManager.getNode(SELF.childClassType) );
		
		//save the currently selected child
		SELF.serviceManager.debugOut(SELF.classType + ".getSelectedChild() ");
		
		var selectedOption = SELF.serviceManager.getSelectedOption( SELF.serviceManager.getNode(SELF.childClassType) );
		for(var i = 0; i < SELF.childData.length; i++) {
			if(selectedOption.value == SELF.childData[i].data.TITLE) {
				
				SELF.serviceManager.debugOut("Contract Child (Capacity) Selected: " + selectedOption.value);
				
				//update the child select etc
				SELF.childData[i].updateChildren();
			}
		}
	}
	SELF.init(data);
};





/**
 * AKA capacity
 * 
 */
AINS.Corporate.contractOptions = function(serviceManager, data, domNode) {
	
	var SELF = this;
	this.classType = "contractOptions";
	this.childClassType = "contractOptionsIPS";
	this.data = data;
	this.serviceManager = serviceManager;

	/**
	 * basic initialiser 
	 * @constructor
	 */	
	 
	this.init = function(data) {
		
		SELF.data = data;
		SELF.childData = [];
		
		for(var i = 0; i < SELF.data.CONTRACTOPTIONIPS.length; i++) {
			SELF.childData.push(new AINS.Corporate.contractOptionsIPS(SELF.serviceManager, SELF.data.CONTRACTOPTIONIPS[i]));
		}
		
		SELF.updateChildren();
	}
	
	/**
	* Sends selected Node To service manager.
	*/
	
	this.nodeSelected = function(){
		
		SELF.serviceManager.nodeSelected(SELF.classType, SELF);
	}
	
	/**
	 * When Called below send Node Values to service manager.
	 */
		
	this.getInstallation = function() { 
			
		return SELF.data.INSTALLATION; 
	} 
	
	this.getPrice = function() {
			
		return SELF.data.PRICE;
	}
	
	this.getDescription = function() {	
		
		var returnedDescription = ", on a " + SELF.data.DESCRIPTION + " speed";
				
		return returnedDescription;
	}
	
	this.getWarning = function() {	
		
		return SELF.data.WARNING;
	}
	
	/**
	 * Sets Atributes for child before appended in Update Children.
	 */

	this.getDomNode = function() {
		
		var serviceNode = document.createElement("option");
		serviceNode.setAttribute("value", SELF.data.TITLE);
		serviceNode.setAttribute("title", SELF.data.DESCRIPTION);
		var serviceNodeText = document.createTextNode(SELF.data.TITLE);
		serviceNode.appendChild(serviceNodeText);
		
		return serviceNode;
	}
	
	/**
	 * Appends infromation to Child(IP).
	 */	
	this.updateChildren = function() {
		
		//SELF.serviceManager.debugOut(SELF.classType + ".updateChildren() " + SELF.data.TITLE);
		//getSelectedOption, setSelectedOptionByValue
		var selectedOption = SELF.serviceManager.getSelectedOption( SELF.serviceManager.getNode(SELF.classType) );
		if(selectedOption) {
			SELF.serviceManager.debugOut(SELF.classType + ".updateChildren() selectedOption: " + selectedOption.value);
		} else {
			SELF.serviceManager.debugOut(SELF.classType + ".updateChildren() selectedOption: " + selectedOption);
		}
		
		var IPDomNode = SELF.serviceManager.getNode(SELF.childClassType);
		if(IPDomNode.onchange == null) {
			IPDomNode.onchange = SELF.getSelectedChild;
		}
		IPDomNode.onchange = SELF.getSelectedChild;
		IPDomNode.innerHTML = "";
		for(var i = 0; i < SELF.childData.length; i++) {
			var newIPNode = SELF.childData[i].getDomNode();
			IPDomNode.appendChild(newIPNode);
			
		}
		SELF.childData[0].nodeSelected();
		SELF.nodeSelected();
	}
	
	/**
	 * Sets selected in child, and self.
	 */
	 
	this.setSelected = function(){
		
		SELF.childData[0].nodeSelected();
		SELF.nodeSelected();
	}
	
	/**
	 * Checks Value of Combo against Array.
	 */
	
	this.getSelectedChild = function() {
		
		var selectedOption = SELF.serviceManager.getSelectedOption( SELF.serviceManager.getNode(SELF.childClassType) );
		for(var i = 0; i < SELF.childData.length; i++) {
			if(selectedOption.value == SELF.childData[i].data.TITLE) {
				SELF.childData[i].updateChildren();
			}
		}
	}
	SELF.init(data);
};

AINS.Corporate.contractOptionsIPS = function(serviceManager, data, domNode) {
	
	var SELF = this;
	this.classType = "contractOptionsIPS";
	this.data = data;
	this.serviceManager = serviceManager;

	/**
	 * basic initialiser 
	 * @constructor
	 */	
	 
	this.init = function() {
		
	}
	
	/**
	* Sends selected Node To service manager.
	*/
			
	this.nodeSelected = function(){
		
		SELF.serviceManager.nodeSelected(SELF.classType, SELF);
	}

	/**
	 * Sets selected in child, and self.
	 */

	this.setSelected = function(){
		
		SELF.nodeSelected();
	}
	
	/**
	 * Sets Atributes for child before appended in Update Children.
	 */
	 
	this.getDomNode = function() {
		
		var serviceNode = document.createElement("option");
		serviceNode.setAttribute("value", SELF.data.TITLE);
		serviceNode.setAttribute("title", SELF.data.DESCRIPTION);
		var serviceNodeText = document.createTextNode(SELF.data.TITLE);
		serviceNode.appendChild(serviceNodeText);
		
		return serviceNode;
	}
	
	this.updateChildren = function() {
		
		SELF.nodeSelected();
	}
	
	this.getInstallation = function() { 
			
		return 0; 
	} 
	
	this.getPrice = function() {
			
		return SELF.data.PRICE;
	}
	
	this.getDescription = function() {	
		var returnedDesription = "";
		
		if(SELF.data.TITLE == "n/a"){
			returnedDesription = "";
		} else{
			returnedDesription = ", with a " + SELF.data.DESCRIPTION + " Download";
		}
		return returnedDesription;
	}
	
	this.getWarning = function() {	
		
		var returnedWarning = SELF.data.WARNING;
		var ipDataCap = SELF.data.CAP;
		var ipDataExcess = SELF.data.EXCESS;
		var ipCap = "";
		var ipExcess = "";
			
		if(ipCap >= 0 && ipExcess >= 0){
		
			if(ipDataExcess <= 0){
				ipExcess = "";
			} else{
				ipExcess =  "Excess data: " + ipDataExcess + "$/MB";
			}
			
			if(ipDataCap <= 0){
				ipCap = "";
			} else{
				ipCap =  " capped at $" + ipDataCap + "";
			}
		}	
		
		returnedWarning += " " + ipExcess + ipCap;
		
		return returnedWarning;
	}
};
