//*BEGIN MODULES.COM CORE*/
var charts = {
	esignal : {
		com : {}
	}
}
var symbols = {
	esignal : {
		com : {}
	}
}

var quotes = {
	esignal : {
		com : {}
	}
}
/**
 * @param defaultParameters
 */
charts.esignal.com.Study = Class.create({
	/**
	 * @param defaultParameters The parameters should be sent in the array format [10,20] 
	 * @param description Comes in as a string 
	 */
	initialize: function(description, defaultParams) {
		this.description = description;
		this.setParameters(defaultParams);
		//We have to create a clone copy of the parameters so that the array references are different.
		this.setUserParameters(defaultParams.clone());
	},
	setCode: function (code) {
		this.code = code;
	},
	getCode: function() {
		return this.code;
	},
	getDescription: function() {
		return this.description;
	},
	getFullDescription: function() {
		return this.description + " [" + this.userParameters + "]";
	},
	getParameter : function(index) {
		return this.getParameters()[index];
	},
	getParameters: function() {
		return this.parameters;
	},
	setParameters: function(params) {
		this.parameters = params;
	},
	getUserParameter : function(index) {
		return this.getUserParameters()[index];
	},
	setUserParameter : function (index, value) {
		this.userParameters[index] = value;
	},
    getUserParameters: function() {
        return this.userParameters;
    },
    setUserParameters: function(parameters) {
		this.userParameters = parameters.clone();
    }
});

charts.esignal.com.StudyUtil = {
	updateUserStudies : function (userStudiesValue, studyCode, isUnset) {
		var study = charts.esignal.com.Studies[studyCode];
		var userStudiesHash = charts.esignal.com.StudyUtil.toUserStudiesHash(userStudiesValue);
		if (isUnset) userStudiesHash.unset(studyCode);
		else userStudiesHash.set(study.getCode(), study.getUserParameters());
		return charts.esignal.com.StudyUtil.toUserStudiesString(userStudiesHash);
	},
	/**
	 * Convert the hash values of selected studies into <study1>(<paramsfor1>);<study2>(<paramsfor2>); format
	 */
	toUserStudiesString : function (hash) {
		
		var stringStudies = "";
		var x = 0;
		hash.each( function(pair) {
			stringStudies += pair.key + "(" + pair.value + ")";
			if (x < (hash.size()-1)) stringStudies += ";";
			x++;;
		});
		return stringStudies;
	},
	/**
	 * <study1>(<paramsfor1>);<study2>(<paramsfor2>); to hash ($H) value of {'<study1>':[param1,param2,param3],'<study2>':[param1]}
	 */
	toUserStudiesHash : function (string) {
		
		var hashStudies = new Hash();
		if (string != null && string != '') {
			var studiesArray = string.split(";");
			for (var x = 0; x < studiesArray.length ; x++) {
				var studyValue = studiesArray[x];
				if (studyValue != null && studyValue != '') {
					var bracketIndex = studyValue.search("\\(");
					hashStudies.set(studyValue.slice(0,bracketIndex), studyValue.slice(bracketIndex+1, studyValue.length-1));
				}
			}
		}
		return hashStudies;
	}
};

charts.esignal.com.FutureSymbolUtil = {
	/**
	 * Converts a given contractYear into actual year.
	 * Assuming current year to be 2010
	 * For contractYear of "1" retuns 2011
	 * For contractYear of "23" returns 2023
	 * For contractYear of "2003" returns 2003
	 * 
	 * 
	 * @return Returns contract year into four character (yyyy) year.
	 */
	convertYear : function(contractYear) {
		var convertedYear = null;
		var today = new Date();
		var currentYear = today.getFullYear();
		if (contractYear.length == 1) {
			for (var i = 0; i <= 10; i++) {
				var tempYear = "" + (currentYear + i);
				if (tempYear.endsWith(contractYear)) {
					return tempYear;
				} 
			}
		}
		if (contractYear.length == 2) {
			for (var i = 11; i <= 20; i++) {
				var tempYear = "" + (currentYear + i);
				if (tempYear.endsWith(contractYear)) {
					return tempYear;
				} 
			}
		}
		if (contractYear.length == 4) {
			return contractYear;
		}
		return convertedYear;
	},
	convertContractYear : function(contractMonth, year) {
		var convertedYear = null;
		var today = new Date();
		var contractMonthMap = {'F' : 1, 'G' : 2, 'H' : 3, 'J' : 4, 'K' : 5, 'M' : 6, 'N' : 7, 'Q' : 8, 'U' : 9, 'V' : 10, 'X' : 11, 'Z' : 12 }; 
		var month = contractMonthMap[contractMonth];

		var contractDate = new Date();
		contractDate.setMonth(month-1);
		contractDate.setYear(year);

		var tenYearDate = new Date();
		tenYearDate.setMonth(today.getMonth(), 26);
		tenYearDate.setYear(today.getFullYear() + 9);

		if (contractDate >= today) {
			if (contractDate > tenYearDate) {
				//Use 2 character
				convertedYear = ("" + contractDate.getFullYear()).substring(2);
			} else {
				//Use 1 character
				convertedYear = ("" + contractDate.getFullYear()).substring(3);
			}
		} else {
			//Use 4 characters
			convertedYear = "" + contractDate.getFullYear();
		}

		return convertedYear;
	}

};

charts.esignal.com.Studies = {
	"BOLL" : new charts.esignal.com.Study("Bollinger Bands", [20,2]),
	"CCI" : new charts.esignal.com.Study("Commodity Channel Index", [20]),
	"DMI" : new charts.esignal.com.Study("Directional Movement Index", [14,1,1,1]),
	"DMA" : new charts.esignal.com.Study("Displaced Moving Average", [4,9,18,14]),
	"ENV" : new charts.esignal.com.Study("Envelope", [10,50,0]),
	"EMA" : new charts.esignal.com.Study("Exp. Moving Average", [4,9,18]),
	"HILOW" : new charts.esignal.com.Study("Highest High/Lowest Low", [20,1]),
	"HLMA" : new charts.esignal.com.Study("High/Low Moving Average", [10,8]),
	"HV" : new charts.esignal.com.Study("Historic Volatility", [20]),
	"LIN" : new charts.esignal.com.Study("Least Sq. Linear Regression", [10]),
	"LOSC" : new charts.esignal.com.Study("Line Oscillator", [6,21,6]),
	"MACD" : new charts.esignal.com.Study("MACD", [12,26,9]),
	"MOM" : new charts.esignal.com.Study("Momentum", [20]),
	"MA" : new charts.esignal.com.Study("Moving Average", [4,9,18]),
	"MSTD" : new charts.esignal.com.Study("Moving Standard Deviation", [20]),
	"OSC" : new charts.esignal.com.Study("Oscillator", [5,10]),
	"PARAB" : new charts.esignal.com.Study("Parabolic", [20,20,200]),
	"PR" : new charts.esignal.com.Study("Percent R", [10]),
	"ROC" : new charts.esignal.com.Study("Rate of Change", [10]),
	"RSI" : new charts.esignal.com.Study("Relative Strength Index", [14]),
	"SSTO" : new charts.esignal.com.Study("Slow Stochastic", [14,3,3,3]),
	"STO" : new charts.esignal.com.Study("Stochastic", [14,3]),
	"VOI" : new charts.esignal.com.Study("Volume and Open Interest", [1,1]),
	"VMA" : new charts.esignal.com.Study("Var. Moving Average", [5,10,20]),
	"WTCL" : new charts.esignal.com.Study("Weighted Close", []),
	"AD" : new charts.esignal.com.Study("Williams Accum. Dist. Index", [])
}

symbols.esignal.com.Symbol = Class.create({
	initialize: function(description, symbol, root, market, exchange) {
		this.description = description;
		this.symbol = symbol;
		this.root = root;
		this.exchange = exchange;
		this.market = market;
	},
	getDescription : function() {
		return this.description;
	},
	getRoot : function() {
		return this.root;
	},
	getSymbol : function() {
		return this.symbol;
	},
	getExchange : function() {
		return this.exchange;
	}
});

symbols.esignal.com.Exchange = Class.create({
	initialize: function(description, id) {
		this.description = description;
		this.id = id;
	},
	getDescription : function() {
		return this.description;
	},
	getId : function() {
		return this.id;
	}
});

symbols.esignal.com.TopSymbol = Class.create( symbols.esignal.com.Symbol, {
	initialize: function($super, description, symbol, root, market, exchange) {
		$super(description, symbol, root, market, exchange);
	},
	
	getFullDescription : function () {
		var ex = "";
		if (this.exchange != null && this.exchange != 'undefined' && this.exchange != '') {
			ex = " {" + this.exchange + "}";
		}
		return this.description + " - " + this.root + ex;
	}
});

quotes.esignal.com.Fields = {
	"desc" : "Contract",
	"delivery" : "Month/Year",
	"last" : "Last",
	"chgoldsettle" : "Change",
	"percentchgoldsettle" : "% Change",
	"open" : "Open",
	"high" : "High",
	"low" : "Low",
	"accuvol" : "Volume",
	"totvol" : "Old Volume",
	"openint" : "Open Interest",
	"dte" : "DTE",
	"bid" : "Bid",
	"ask" : "Ask",
	"bidaskspread" : "Bid Ask Spread",
	"chgopen" : "Change (Open)",
	"percentchgopen" : "% Change (Open)",
	"newsettle" : "New Settle",
	"oldsettle" : "Old Settle",
	"dispname" : "Symbol",
	"root" : "Root",	
	"month" : "Month",
	"year" : "Year",
	"shortyear" : "Short Year",
	"shortmonth" : "Short Month",
	"exchg" : "Exchange",
	"market" : "Market",
	"datetime" : "Date and Time",
	"time" : "Time",
	"date" : "Date",
	"type" : "Type",
	"timezone" : "Time Zone",
	"recent" : "Recent",
	"activeprice" : "Active Price",
	"ask1" : "Ask1",
	"ask2" : "Ask2",
	"ask3" : "Ask3",
	"bid1" : "Bid1",
	"bid2" : "Bid2",
	"bid3" : "Bid3",
	"annhigh" : "Annual High",
	"annlow" : "Annual Low",	
	"wh52date" : "52 Week High Date",
	"wl52date" : "52 Week Low Date",
	"ptval" : "Point Value",
	"minimumincrement" : "Min. Increment",
	"delay" : "Delay",
	"exp" : "Expiration Date"
			
};


quotes.esignal.com.QuoteFieldsUtil = {
	updateQuoteFields : function (quoteFieldsValue, fieldCode, isUnset) {
		var quoteFieldsHash = quotes.esignal.com.QuoteFieldsUtil.toQuoteFieldsHash(quoteFieldsValue);
		if (fieldCode != '') {
			var field = quotes.esignal.com.Fields[fieldCode];			
			if (isUnset) quoteFieldsHash.unset(fieldCode);
			else quoteFieldsHash.set(fieldCode, field);
		}
		return quotes.esignal.com.QuoteFieldsUtil.toQuoteFieldsString(quoteFieldsHash);		
	},
	/**
	 * Convert the hash values of selected fields into string format
	 */
	toQuoteFieldsString : function (hash) {
		var stringFields = "";
		var x = 0;
		hash.each( function(pair) {
			stringFields += pair.key;
			if (x < (hash.size()-1)) stringFields += ",";
			x++;;
		});
		return stringFields;
	},
	/**
	 * comma separated fields to hash ($H) value of {'key':'value'}
	 */
	toQuoteFieldsHash : function (string) {
		var hashFields = new Hash();
		if (string != null && string != '') {
			var fieldsArray = string.split(",");
			for (var x = 0; x < fieldsArray.length ; x++) {
				var fieldKey = fieldsArray[x];
				hashFields.set(fieldKey, quotes.esignal.com.Fields[fieldKey]);
			}
		}
		return hashFields;
	},
	// to get the comma separated values of all the options of a selector field
	selectorToString : function (selector) {
		var selFields = selector.childElements();
		var fieldsToString = "";
		for (var x = 0; x < selFields.length; x++) {
			fieldsToString += selFields[x].value;
			if(x < selFields.length -1) fieldsToString += ",";
		}
		return fieldsToString;
	}
	
};

symbols.esignal.com.FormInputUtils = {
	sendalert : function() {
		alert('utils');
	},

	sortOptions : function (selectEle) {
		var sortedOptions = $A(selectEle.options).sort( function(optionOne,optionTwo) { 
				return (optionOne.text.toLowerCase() < optionTwo.text.toLowerCase() ) ? -1 : 1; 
			});
		//IE only works with appendChild method.  We cannot assign option via index, e.g. selectEle.options[index] = sortedOptions[index]
		var lengthS = selectEle.length;
		for (var x = 0; x < lengthS ; x++) {
			selectEle.appendChild(sortedOptions[x]);
		}
	},

	moveOptions : function (from, to) {
		var movedOptions = new Array();
		while (from.selectedIndex != -1) {
			movedOptions.push(from.options.item(from.selectedIndex));
			to.appendChild(from.options.item(from.selectedIndex));
		}
		while (to.selectedIndex != -1) {
			to.selectedIndex = -1;
		}
		return movedOptions;
	},

	moveUp : function (selectEle) {
		//take each selected item and move it up one
		for (var x = 0; x < selectEle.length; x++) {
			if (selectEle.options[x].selected && symbols.esignal.com.FormInputUtils.iCanMove(selectEle, x, true)) {
				var tmp = new Option(selectEle.options[x].text, selectEle.options[x].value);
				selectEle.options[x].value = selectEle.options[x-1].value;
				selectEle.options[x].text = selectEle.options[x-1].text;
				if (!selectEle.options[x-1].selected) selectEle.options[x].selected = false;	
				selectEle.options[x-1].value = tmp.value;
				selectEle.options[x-1].text = tmp.text;
				selectEle.options[x-1].selected = true;
			}
		}
	},
	
	moveDown : function (selectEle) {
		for (var x = selectEle.length - 1; x >= 0; x--) {
			if (selectEle.options[x].selected && symbols.esignal.com.FormInputUtils.iCanMove(selectEle, x, false)) {
				var tmp = new Option(selectEle.options[x].text, selectEle.options[x].value);
				selectEle.options[x].value = selectEle.options[x+1].value;
				selectEle.options[x].text = selectEle.options[x+1].text;
				if (!selectEle.options[x+1].selected) selectEle.options[x].selected = false;	
				selectEle.options[x+1].value = tmp.value;
				selectEle.options[x+1].text = tmp.text;
				selectEle.options[x+1].selected = true;
			}
		}
	},

	iCanMove : function (arr, index, moveUp) {
		//we need to determine if a selected item can move up.
		//basically we need to search up or down the list to see if there is a nonselected item to move with
		var iCanMove = false;
		if (moveUp) {
			for (var x = index; x >= 0; x--) {
				if (!arr.options[x].selected) {
					iCanMove = true;
					break;
				}
			}
		} else {
			for (var x = index; x < arr.length; x++) {
				if (!arr.options[x].selected) {
					iCanMove = true;
					break;
				}
			}			
		}			
		return iCanMove;
	},

	// to get the comma separated values of all the options of a selector field
	selectOptionsToCommaSeparatedString : function (selectEle) {
		var selectOptions = selectEle.childElements();
		var selectOptionsString = "";
		for (var x = 0; x < selectOptions.length; x++) {
			selectOptionsString += selectOptions[x].value;
			if(x < selectOptions.length -1) selectOptionsString += ",";
		}
		return selectOptionsString;
	}
	
};


