
var mwssTargets = new Array();
var mwssUpdateGroup = new Array();
var ssLastUpdate = 0;

var mwBATSTargets = new Array();
var mwBATSUpdateGroup = new Array();
var BATSLastUpdate = 0;
var GMTOffset = -5;
var sCurrDate;

var strServerTime = 0;
var strServerDay = 5;
var blnPullBATS = false;


function ssListener() {
	var i = 0;
	var g = 0;
	var c = 0;
	var o;

	var spans = document.getElementsByTagName('span');
	while(o=spans.item(c))  {		
		c++;
		var strSource = o.getAttribute("stream");		

		if (strSource!=undefined) {
			o.id = "mwssTar" + i;
			var strFields = strSource.split("|");
	
			mwssTargets[i] = new Object();
			mwssTargets[i].tarid = i;
			mwssTargets[i].symbol = strFields[0].toUpperCase();
			mwssTargets[i].source = strFields[1];
			mwssTargets[i].data = strFields[2];
			mwssTargets[i].freq = 1.5;
			mwssTargets[i].format = strFields[4];
			mwssTargets[i].lastclose = 0;			
			mwssTargets[i].lastvalue = 0;
			mwssTargets[i].target = o;
			mwssTargets[i].lastupdate = 0;
			
			switch (mwssTargets[i].symbol) {
			    case "TYX":
			    case "FVX":
			    case "TNX":
			    case "IRX.X":
				mwssTargets[i].format = 0.1;				
			}
			i++;

		}

	}
	
	//sort by symbol
	mwssTargets.sort(fnSortSymbols);

	var d = new Date();
	//next create groups of tickers for each interval 
	for (var j = 0;j<i;j++) {
		if (g > 0) {
			//append if not already in list
			if (mwssUpdateGroup[g-1].symbols.indexOf("|"+ mwssTargets[j].symbol + "|")<0) {
				mwssUpdateGroup[g-1].symbols += "|"+ mwssTargets[j].symbol + "|";
			}

		} else {
			mwssUpdateGroup[g] = new Object();
			mwssUpdateGroup[g].freq = mwssTargets[j].freq;
			mwssUpdateGroup[g].lastupdated = d.getTime();
			mwssUpdateGroup[g].symbols = "|"+ mwssTargets[j].symbol + "|";	
			g++;
		}
	}

	//create intervals
	for (var k = 0;k<g;k++) {
		mwssUpdateGroup[k].freq*= 1000; //convert to milliseconds
		mwssUpdateGroup[k].interval = setInterval("fnSSUpdateGroup(" + k + ",1);",mwssUpdateGroup[k].freq);
		
		var tSymbols = mwssUpdateGroup[k].symbols;
		
		tSymbols = xreplace(tSymbols,"||",",");
		tSymbols = xreplace(tSymbols,"|","");


		mwssUpdateGroup[k].symbols = ssURLEncode(tSymbols);
		setInterval("fnSSUpdateGroup(" + k + ",2);",30000);
		fnSSUpdateGroup(k,2);
	}  	
}


function xreplace(checkMe,toberep,repwith){

	var temp = checkMe;	
	var i = temp.indexOf(toberep);
	
	while(i > -1) {	
		temp = temp.replace(toberep, repwith);	
		i = temp.indexOf(toberep, i + repwith.length + 1);	
	}	
	return temp;
}

function ssURLEncode (clearString) {
  var output = '';
  var x = 0;
  clearString = clearString.toString();
  var regex = /(^[a-zA-Z0-9_.]*)/;
  while (x < clearString.length) {
    var match = regex.exec(clearString.substr(x));
    if (match != null && match.length > 1 && match[1] != '') {
    	output += match[1];
      x += match[1].length;
    } else {
      if (clearString[x] == ' ')
        output += '+';
      else {
        var charCode = clearString.charCodeAt(x);
        var hexVal = charCode.toString(16);
        output += '%' + ( hexVal.length < 2 ? '0' : '' ) + hexVal.toUpperCase();
      }
      x++;
    }
  }
  return output;
}


function fnSortSymbols(a,b) {
	aa = a.symbol;
	bb = b.symbol;
	if (aa==bb) return 0;
	if (aa<bb) return -1;		
	return 1;
}


function fnSortBySymbol() {	
	mwssTargets.sort(fnSortSymbols);
}


function fnMarketHours() {
	if (strServerDay > 1 && strServerDay < 7) {
		return (strServerTime > 929 && strServerTime < 1616);
	} else {
		return false;
	}
}


function fnSetCurrDate() {
	var cDate = new Date();
	//cDate.setHours(cDate.getHours() + cDate.getTimezoneOffset() + GMTOffset);
	sCurrDate = formatDate(cDate,"yyyyMMdd");
	//sCurrDate = "20090206";
}

function fnSSUpdateGroup(groupID,t) {
	if (t==2 || fnMarketHours()) {
		if (t==1 && blnPullBATS) t=3;
		blnPullBATS = !blnPullBATS;
		var dTimeStamp = new Date();
		var sURL = "://streamer1.mworld.com/sitestream/ss.asp?sym=" + mwssUpdateGroup[groupID].symbols + "&i=" + groupID +"&u=" + BATSLastUpdate + "&t=" + t + "&s=" + dTimeStamp.getTime();

		//var sURL = "://streamer1.mworld.com/ssProcess/ssProcess.aspx?symbols=" + mwssUpdateGroup[groupID].symbols + "&i=" + groupID +"&u=" + BATSLastUpdate + "&t=" + t + "&s=" + dTimeStamp.getTime();
		var loc = new String(window.parent.document.location); 
		if (loc.indexOf("https://")!= -1) {
			sURL = "https" + sURL;
		} else {
			sURL = "http" + sURL;
		}

		//var sURL = "sitestream/d.w?sym=" + mwssUpdateGroup[groupID].symbols + "&i=" + groupID +"&u=" + ssLastUpdate + "&t=" + t + "&s=" + dTimeStamp.getTime();
		
		var tscript=document.getElementById("script_FetchData");
		if (tscript) tscript.parentNode.removeChild(tscript);
		tscript=document.createElement("script");
		tscript.id="script_FetchData";
		tscript.src=sURL;
		if (document.getElementsByTagName("head")[0]) {
			document.getElementsByTagName("head")[0].appendChild(tscript);
		}
	}
}


//parse data and send to requested locations
function fnSSResponse(groupid,nUpdate,rResult,source) {
	if (nUpdate >= ssLastUpdate) {
		ssLastUpdate = nUpdate;
	  	var portrows = new Array();
	  	var portcols = new Array();
		var sSymbol="";
		var i =0;
		
		portrows = rResult.split("|")
		var arLen=portrows.length;

		for ( var n=0; n<arLen; ++n ){	
		
			portcols = portrows[n].split(",");
			if (portcols[4] > 0 || portcols[7] > 0) {
				if (portcols[0].indexOf("(")>0) {
					sSymbol = portcols[0].substring(0,(portcols[0].indexOf("(")));
				} else {
					sSymbol = portcols[0];
				}
				sSymbol = unescape(sSymbol);
				var tT = parseFloat(portcols[19]+portcols[12]);

				//find target with matching symbol
				while(i < mwssTargets.length && mwssTargets[i].symbol != sSymbol) i++;
				while(i < mwssTargets.length && mwssTargets[i].symbol == sSymbol) {
					
					if (tT >= mwssTargets[i].lastupdate || mwssTargets[i].data == "VMP") {
						
						if (mwssTargets[i].source == 0) {
							fnSSUpdateTarget(i,portcols,source,tT);							
						} else if (mwssTargets[i].source == 1 && source < 3) {
							fnSSUpdateTarget(i,portcols,source,tT);
						} else if (mwssTargets[i].source == 3 && source == 3) {
							fnSSUpdateTarget(i,portcols,source,tT);
						} else if (mwssTargets[i].source == 3 && source == 2) {
							if (sCurrDate == portcols[19]) {
								mwssTargets[i].lastclose =  parseFloat(portcols[7]);
							} else {
								mwssTargets[i].lastclose =  parseFloat(portcols[1]);
							}
						}
					}
					i++;
				}
			}
		}
	}
	if (source==2) {
		var cDate = new Date();
		//cDate.setHours(cDate.getHours() + cDate.getTimezoneOffset() + GMTOffset); 
		sCurrDate = formatDate(cDate,"yyyyMMdd");
		if (!fnMarketHours()) fnHideBATS();
	}
}

function fnHideBATS() {
	for (var i=0;i < mwssTargets.length;i++) {
		if (mwssTargets[i].source == 3) mwssTargets[i].target.innerHTML = "";			
	}
}

function fnBATSUpdateTarget(i,RawData) {
	var nDig = 2;
	var sOut = "";
	if (Math.abs(RawData[1]) < 1) nDig = 4;
	if (mwssTargets[i].lastclose > 0  && sCurrDate == RawData[19]) {
		sOut = "<div style='border:1px solid black;margin:5px;margin-top:0px;padding:5px;padding-top:0px;height:44px;text-align:left;position:relative:x:-7px;'><span style='font-weight:bold;font-size:11px;margin-top:2px;float:left;'><a href='m.w?lp=Help&sp=VC&pid=375'>BATS Realtime Quote <span class='batsbutton'></span></a></span><span style='float:right;'><font size=3><b><span style='white-space:nowrap;";
		RawData[16] = RawData[1] - mwssTargets[i].lastclose;
		RawData[17] = 100*RawData[16]/mwssTargets[i].lastclose;
		if (RawData[1] > mwssTargets[i].lastvalue) sOut += "background:#ccffcc;'>"
		else if (RawData[1] < mwssTargets[i].lastvalue) sOut += "background:#ffcccc;'>"
		else sOut += "'>"
		sOut +=  fnSSFormatValue(RawData[1],nDig) + " " +  fnSSFormatChange(RawData[16],"value",nDig,true,"","") + " " + fnSSFormatChange(RawData[17],"value",nDig,true,"","%") + "</span></b></font><br><font size=1>";
		sOut += "as of " + fnSSConvertDate(RawData[19],RawData[12],RawData[18],"MM/dd/yyyy hh:mm:ss a") + "</font></span><br clear=all></div>";
		mwssTargets[i].lastvalue = RawData[1];
	}
	return sOut;				
}

function fnBATSUpdateAvail(i,RawData) {
	var sOut = "";	
	if (mwssTargets[i].lastclose > 0  && sCurrDate == RawData[19]) {
		sOut = "<br><a class='sbl' href='m.w?lp=Help&sp=VC&pid=375'>* BATS Realtime Quote</a>";		
	}
	return sOut;				
}

function fnSSUpdateTarget(i,RawData,source,tT) {
	mwssTargets[i].lastupdate = tT;
	if (sCurrDate == RawData[19] || (source==1 && mwssTargets[i].source==0)) {
		if (sCurrDate != RawData[19] && (source==1 && mwssTargets[i].source==0)) {
				RawData[16] = 0;
				RawData[17] = 0;
		}
		if (source==3) {
			if (mwssTargets[i].lastclose > 0) {
				RawData[16] = RawData[1] - mwssTargets[i].lastclose;
				RawData[17] = 100*RawData[16]/mwssTargets[i].lastclose;
				if (mwssTargets[i].source == 1) return;
			} else {
				return;
			}
		}
		//console.log(source + "," + RawData[0]);
		var nDig = 2;
		var nValue = RawData[1];
		var nChange = RawData[16];
		var nPerc = RawData[17];
		var nValue = RawData[1] * mwssTargets[i].format;
		var nChange = RawData[16] * mwssTargets[i].format;
		var nPerc = RawData[17];
		var nDir = "";
		var sOut = "<span";
		if (Math.abs(nValue) < 1) nDig = 4;
		if (mwssTargets[i].format == 0.1) nDig = 4;
		if (source==2) {
			sOut += ">" 
			nValue = RawData[1];
			nChange = RawData[16];
			nPerc = RawData[17];
			mwssTargets[i].lastclose = parseFloat(RawData[7]);
		} else {
			if (RawData[1] > mwssTargets[i].lastvalue) {sOut += " style='background:#ccffcc;'>";nDir="UP"; }
			else if (RawData[1] < mwssTargets[i].lastvalue) {sOut += " style='background:#ffcccc;'>";nDir="DN"}
			else sOut += ">"
			if (source ==1) mwssTargets[i].lastclose = parseFloat(RawData[7]);
		}
		
	
		switch (mwssTargets[i].data) {
			case "P": sOut += fnSSFormatValue(nValue,nDig) + "</span>";break;
			case "C": sOut += fnSSFormatChange(nChange,"value",nDig,true,"","") + "</span>";break;
			case "R": sOut += fnSSFormatChange(nPerc,"value",nDig,true,"","%") + "</span>";break;
			case "CR": sOut += fnSSFormatChange(nChange,"value",nDig,true,"","") + " " + fnSSFormatChange(nPerc,"value",2,true,"","%") + "</span>";break;
			case "PCR": sOut += fnSSFormatValue(nValue,nDig) + " " + fnSSFormatChange(nChange,"value",nDig,true,"","") + " " + fnSSFormatChange(nPerc,"value",2,true,"","%") + "</span>";break;
			case "DT": sOut = fnSSConvertDate(RawData[19],RawData[12],RawData[18],"MM/dd/yyyy hh:mm:ss a");break;
			case "BATS": if (source==3) sOut = fnBATSUpdateTarget(i,RawData);break;			
			case "SR": sOut = fnSSSBChart(true,nValue,nChange,nPerc,nDig,nDir,source);break;
			case "SL": sOut = fnSSSBChart(false,nValue,nChange,nPerc,nDig,nDir,source);break;			
			case "SBP": sOut = fnSSSBTable(mwssTargets[i].data,nValue,nChange,nPerc,nDig,nDir,source);break;
			case "SBC": sOut = fnSSSBTable(mwssTargets[i].data,nValue,nChange,nPerc,nDig,nDir,source);break;			
			case "MP": sOut = fnSSMPMiddle(nValue,nChange,mwssTargets[i].symbol);break;
			case "MU":sOut = fnSSMPChart(true,nValue,nChange,nPerc);break;
			case "MD":sOut = fnSSMPChart(false,nValue,nChange,nPerc);break;	
			case "SDT": sOut = fnSmallTime(RawData[19],RawData[12],RawData[18],"hh:mm:ss") ;break;
			case "SDTE": sOut = fnSmallDayTime(RawData[19],RawData[12],RawData[18],"E hh:mm:ss") ;break;
			case "O": sOut = fnSSFormatValue(RawData[8],nDig);break;
			case "H": sOut = fnSSFormatValue(RawData[5],nDig);break;
			case "L": sOut = fnSSFormatValue(RawData[6],nDig);break;
			case "CL": sOut = fnSSFormatValue(RawData[7],nDig);break;
			case "V": sOut = addCommas(fnSSFormatValue(RawData[4]/1000,1)) + " thou";break;
			case "VMP": sOut = fnSSMarketVolume(RawData[4]);break;
			case "VMIL": sOut = addCommas(fnSSFormatValue(RawData[4]/1000000,1));break;
			case "VM": sOut = addCommas(fnSSFormatValue(nValue,0));break;
			case "MC": sOut = addCommas(fnSSFormatValue(RawData[1]*mwssTargets[i].format/1000000,0)) + " mil";break;
			case "PE": if (mwssTargets[i].format > 0 ) {sOut = fnSSFormatValue(RawData[1]/mwssTargets[i].format,1);} else {sOut = "-"; } break;
			case "DLY": sOut = (source==3)?"*":"";break;
			case "BAV": if (source==3) sOut = fnBATSUpdateAvail(i,RawData);break;
			case "CUP": sOut += fnSSFormatValue(nValue,4) + "</span>";break;
			case "CUCR":  sOut += fnSSFormatChange(nChange,"value",4,true,"","") + " " + fnSSFormatChange(nPerc,"value",2,true,"","%") + "</span>";break;
		}
		mwssTargets[i].target.innerHTML = sOut;
		mwssTargets[i].lastvalue = RawData[1];
	} else {
		if (source == 2) {
			mwssTargets[i].lastclose =  parseFloat(RawData[1]);
		}
	}
}

function fnSSFormatValue(sValue,nDig) {
	if (isNaN(sValue)) {
		return "";
	} else {
		sValue = parseFloat(sValue);	
		if (nDig == 0) {
			return Math.round(sValue);
		} else {
			return sValue.toFixed(nDig);
		}
	}
}

function fnSSFormatChange(sValue,cStyle,nDig,bPlus,sPre,sSuf) {
	var sOut;
	
	if (isNaN(sValue)) {
		return "";
	} else {
		sValue = parseFloat(sValue);		
		if (nDig > 0) sValue = sValue.toFixed(nDig);
		sOut = sPre + sValue + sSuf;
		if (sValue > 0) {
			if (bPlus) sOut = "+" + sOut;
			sOut = "<span class='" + cStyle + "_up'>" + sOut;
		} else if (sValue ==0) {
			sOut = "<span class='" + cStyle + "_nc'>" + sOut;
		} else {
			sOut = "<span class='" + cStyle + "_dn'>" + sOut;
		}
		sOut += "</span>"
		return sOut;
	}
}

function fnSSConvertDate(rDate,rTime,rOffset,sFormat) {
	var sT;
	var sT2; 

	GMTOffset = rOffset;

	rTime = parseFloat(rTime) + 10000 + rOffset*10000;
	if (rTime < 100000) rTime = "0" + rTime.toString();
	 else rTime = rTime.toString();

	sT = rDate + rTime;
	var sT = new Date(getDateFromFormat(sT,"yyyyMMddkkmmss"));	

	return formatDate(sT,sFormat);
}

function fnSmallTime(rDate,rTime,rOffset,sFormat) {
	var sT;
	var sT2; 

	rTime = parseFloat(rTime) + 10000 + rOffset*10000;
	sT = rDate + rTime.toString();
	var sT = new Date(getDateFromFormat(sT,"yyyyMMddkkmmss"));	
	
	sT2 = formatDate(sT,"hh");
	if (parseInt(sT2) > 16) {
		return "close";
	} else {
		return formatDate(sT,sFormat);
	}
	
}

function fnSmallDayTime(rDate,rTime,rOffset,sFormat) {
	var sT;
	var sT2; 

	rTime = parseFloat(rTime) + 10000 + rOffset*10000;
	sT = rDate + rTime.toString();
	var sT = new Date(getDateFromFormat(sT,"yyyyMMddkkmmss"));	
	
	sT2 = formatDate(sT,"hh");
	if (parseInt(sT2) > 16) {
		return formatDate(sT,"EE") + " close";
	} else {
		return formatDate(sT,sFormat);
	}
	
}

function fnSSMarketVolume(volume) {
	if (strServerTime > 929 && strServerTime < 945) {
		return "-";
	} else {
		return addCommas(Math.round(volume/1000));
	}
}

function fnSSSBTable(sType,nPrice,nChange,cPerc,nDig,nDir) {
	var strOut;
	
	if (sType=="SBP") {
	     strOut = "<font size=1 Class='SideBar" + nDir + "'>" + fnSSFormatValue(nPrice,nDig);
	} else {
	     if (nChange ==0) {
		strOut = "<font size=1 Class='SideBar" + nDir + "'>unch";
	     } else {                              
             	strOut = "<font size=1 Class='SideBar" + nDir + "'>" + fnSSFormatChange(nChange,"sbvalue",nDig,true,"","")
	     }
        }
	return strOut;
}



function fnSSSBChart(bRight,nPrice,nChange,cPerc,nDig,nDir) {
	var strOut;
	
	if (bRight) {
		if (cPerc > 0) {
		     if (cPerc > 5) cPerc = 5;
		     cPerc = Math.round(cPerc * 8);
                     strOut = "<span class='sbup_bar' style='width:" + cPerc + "px;'></span><span class='sbup_head'></span>";
		} else if (cPerc == 0) {
		     strOut = "<span style='width:2px;height:20px;display:block;'></span>";
		} else {
		     if (nChange ==0) {
			strOut = "<font size=1 Class='SideBar" + nDir + "'>" + fnSSFormatValue(nPrice,nDig) + "<br>unch";
		     } else {                              
                     	strOut = "<font size=1 Class='SideBar" + nDir + "'>" + fnSSFormatValue(nPrice,nDig) + "<br>" + fnSSFormatChange(nChange,"sbvalue",nDig,true,"","");
		     }
                }

	} else {
		if (cPerc < 0) {
		     if (cPerc < -5) cPerc = -5;
		     cPerc = Math.round(Math.abs(cPerc) * 8);
                     strOut = "<span class='sbdn_head'></span><span class='sbdn_bar' style='width:" + cPerc + "px'>";
		} else {
		     if (nChange ==0) {
			strOut = "<font size=1 Class='SideBar" + nDir + "'>" + fnSSFormatValue(nPrice,nDig) + "<br>unch";
		     } else {                              
                     	strOut = "<font size=1 Class='SideBar" + nDir + "'>" + fnSSFormatValue(nPrice,nDig) + "<br>" + fnSSFormatChange(nChange,"sbvalue",nDig,true,"","");
		     }
                }
	}
	//console.log(strOut);
	return strOut;
}

function fnSSMPChart(bTop,nPrice,nChange,cPerc) {
	var strOut;

	if (bTop) {
		if (cPerc > 0) {
		     if (cPerc > 5) cPerc = 5;
		     cPerc = Math.round(cPerc * 12);
                     strOut = fnSSFormatChange(nChange,"value",1,true,"","") + "<br><span class='mpup_head'></span><br><span class='mpup_bar' style='height:" + cPerc + "px'></span>";
		} else {
		    strOut = "<div style='width:40px;height:16px;display:block;'></div>";		     
                }

	} else {
		if (cPerc < 0) {
		     if (cPerc < -5) cPerc = -5;
		     cPerc = Math.round(Math.abs(cPerc) * 12);
                     strOut = "<span class='mpdn_bar' style='height:" + cPerc + "px'></span><br><span class='mpdn_head'></span><br>" + fnSSFormatChange(nChange,"value",1,true,"","");
		}  else if (cPerc == 0) {
		strOut = "<div style='width:40px;height:1px;display:block;'></div><span style='font-weight:normal;font-size:10px;'>no<br>change</font>";		     

		}  else {
		    strOut = "<div style='width:40px;height:16px;display:block;'></div>";		     
                }
	}
	//console.log(strOut);
	return strOut;
}

function fnSSMPMiddle(nPrice,nDir,nItem) {
	var strCode;
	var strName;
	var strColor;
	
	switch (nItem) {
		case "$INDU": strCode = "30"; strName = "Dow";break;
		case "$SP": strCode = "SP"; strName = "S&P 500";break;
		case "$NYA": strCode = "NY"; strName = "NYSE";break;
		case "XAX": strCode = "AM"; strName = "AMEX";break;
		case "$COMPQ": strCode = "NQ"; strName = "NASDAQ";break;
	}
	strColor = "up"; 
	if (nDir < 0) strColor = "dn"; 
	
	return "<span class='mpmid_" + strColor + "'><a href='m.w?lp=mpp&Page=DC" + strCode +  "' onMouseOver='bpShow(this);' onMouseOut='bpHide();'>" + strName + "<br>" + fnSSFormatValue(nPrice,0) + "</a></span>";
	
}



function addCommas(nStr) {
	nStr += '';
	x = nStr.split('.');
	x1 = x[0];
	x2 = x.length > 1 ? '.' + x[1] : '';
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(x1)) {
		x1 = x1.replace(rgx, '$1' + ',' + '$2');
	}
	return x1 + x2;
}



// ===================================================================
// Date Functions Courtesy of:
// Author: Matt Kruse <matt@mattkruse.com>
// WWW: http://www.mattkruse.com/
// ===================================================================

var MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
var DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');
function LZ(x) {return(x<0||x>9?"":"0")+x}

function isDate(val,format) {
	var date=getDateFromFormat(val,format);
	if (date==0) { return false; }
	return true;
	}

function compareDates(date1,dateformat1,date2,dateformat2) {
	var d1=getDateFromFormat(date1,dateformat1);
	var d2=getDateFromFormat(date2,dateformat2);
	if (d1==0 || d2==0) {
		return -1;
		}
	else if (d1 > d2) {
		return 1;
		}
	return 0;
	}

function formatDate(date,format) {
	format=format+"";
	var result="";
	var i_format=0;
	var c="";
	var token="";
	var y=date.getYear()+"";
	var M=date.getMonth()+1;
	var d=date.getDate();
	var E=date.getDay();
	var H=date.getHours();
	var m=date.getMinutes();
	var s=date.getSeconds();
	var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
	// Convert real date parts into formatted versions
	var value=new Object();
	if (y.length < 4) {y=""+(y-0+1900);}
	value["y"]=""+y;
	value["yyyy"]=y;
	value["yy"]=y.substring(2,4);
	value["M"]=M;
	value["MM"]=LZ(M);
	value["MMM"]=MONTH_NAMES[M-1];
	value["NNN"]=MONTH_NAMES[M+11];
	value["d"]=d;
	value["dd"]=LZ(d);
	value["E"]=DAY_NAMES[E+7];
	value["EE"]=DAY_NAMES[E];
	value["H"]=H;
	value["HH"]=LZ(H);
	if (H==0){value["h"]=12;}
	else if (H>12){value["h"]=H-12;}
	else {value["h"]=H;}
	value["hh"]=LZ(value["h"]);
	if (H>11){value["K"]=H-12;} else {value["K"]=H;}
	value["k"]=H+1;
	value["KK"]=LZ(value["K"]);
	value["kk"]=LZ(value["k"]);
	if (H > 11) { value["a"]="PM"; }
	else { value["a"]="AM"; }
	value["m"]=m;
	value["mm"]=LZ(m);
	value["s"]=s;
	value["ss"]=LZ(s);
	while (i_format < format.length) {
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
			token += format.charAt(i_format++);
			}
		if (value[token] != null) { result=result + value[token]; }
		else { result=result + token; }
		}
	return result;
	}

function _isInteger(val) {
	var digits="1234567890";
	for (var i=0; i < val.length; i++) {
		if (digits.indexOf(val.charAt(i))==-1) { return false; }
		}
	return true;
	}

function _getInt(str,i,minlength,maxlength) {
	for (var x=maxlength; x>=minlength; x--) {
		var token=str.substring(i,i+x);
		if (token.length < minlength) { return null; }
		if (_isInteger(token)) { return token; }
		}
	return null;
	}

function getDateFromFormat(val,format) {
	val=val+"";
	format=format+"";
	var i_val=0;
	var i_format=0;
	var c="";
	var token="";
	var token2="";
	var x,y;
	var now=new Date();
	var year=now.getYear();
	var month=now.getMonth()+1;
	var date=1;
	var hh=now.getHours();
	var mm=now.getMinutes();
	var ss=now.getSeconds();
	var ampm="";
	
	while (i_format < format.length) {
		// Get next token from format string
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
			token += format.charAt(i_format++);
			}
		// Extract contents of value based on format token
		if (token=="yyyy" || token=="yy" || token=="y") {
			if (token=="yyyy") { x=4;y=4; }
			if (token=="yy")   { x=2;y=2; }
			if (token=="y")    { x=2;y=4; }
			year=_getInt(val,i_val,x,y);
			if (year==null) { return 0; }
			i_val += year.length;
			if (year.length==2) {
				if (year > 70) { year=1900+(year-0); }
				else { year=2000+(year-0); }
				}
			}
		else if (token=="MMM"||token=="NNN"){
			month=0;
			for (var i=0; i<MONTH_NAMES.length; i++) {
				var month_name=MONTH_NAMES[i];
				if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
					if (token=="MMM"||(token=="NNN"&&i>11)) {
						month=i+1;
						if (month>12) { month -= 12; }
						i_val += month_name.length;
						break;
						}
					}
				}
			if ((month < 1)||(month>12)){return 0;}
			}
		else if (token=="EE"||token=="E"){
			for (var i=0; i<DAY_NAMES.length; i++) {
				var day_name=DAY_NAMES[i];
				if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
					i_val += day_name.length;
					break;
					}
				}
			}
		else if (token=="MM"||token=="M") {
			month=_getInt(val,i_val,token.length,2);
			if(month==null||(month<1)||(month>12)){return 0;}
			i_val+=month.length;}
		else if (token=="dd"||token=="d") {
			date=_getInt(val,i_val,token.length,2);
			if(date==null||(date<1)||(date>31)){return 0;}
			i_val+=date.length;}
		else if (token=="hh"||token=="h") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<1)||(hh>12)){return 0;}
			i_val+=hh.length;}
		else if (token=="HH"||token=="H") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<0)||(hh>23)){return 0;}
			i_val+=hh.length;}
		else if (token=="KK"||token=="K") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<0)||(hh>11)){return 0;}
			i_val+=hh.length;}
		else if (token=="kk"||token=="k") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<1)||(hh>24)){return 0;}
			i_val+=hh.length;hh--;}
		else if (token=="mm"||token=="m") {
			mm=_getInt(val,i_val,token.length,2);
			if(mm==null||(mm<0)||(mm>59)){return 0;}
			i_val+=mm.length;}
		else if (token=="ss"||token=="s") {
			ss=_getInt(val,i_val,token.length,2);
			if(ss==null||(ss<0)||(ss>59)){return 0;}
			i_val+=ss.length;}
		else if (token=="a") {
			if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="AM";}
			else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="PM";}
			else {return 0;}
			i_val+=2;}
		else {
			if (val.substring(i_val,i_val+token.length)!=token) {return 0;}
			else {i_val+=token.length;}
			}
		}
	// If there are any trailing characters left in the value, it doesn't match
	if (i_val != val.length) { return 0; }
	// Is date valid for month?
	if (month==2) {
		// Check for leap year
		if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
			if (date > 29){ return 0; }
			}
		else { if (date > 28) { return 0; } }
		}
	if ((month==4)||(month==6)||(month==9)||(month==11)) {
		if (date > 30) { return 0; }
		}
	// Correct hours value
	if (hh<12 && ampm=="PM") { hh=hh-0+12; }
	else if (hh>11 && ampm=="AM") { hh-=12; }
	var newdate=new Date(year,month-1,date,hh,mm,ss);
	return newdate.getTime();
	}

function parseDate(val) {
	var preferEuro=(arguments.length==2)?arguments[1]:false;
	generalFormats=new Array('y-M-d','MMM d, y','MMM d,y','y-MMM-d','d-MMM-y','MMM d');
	monthFirst=new Array('M/d/y','M-d-y','M.d.y','MMM-d','M/d','M-d');
	dateFirst =new Array('d/M/y','d-M-y','d.M.y','d-MMM','d/M','d-M');
	var checkList=new Array('generalFormats',preferEuro?'dateFirst':'monthFirst',preferEuro?'monthFirst':'dateFirst');
	var d=null;
	for (var i=0; i<checkList.length; i++) {
		var l=window[checkList[i]];
		for (var j=0; j<l.length; j++) {
			d=getDateFromFormat(val,l[j]);
			if (d!=0) { return new Date(d); }
			}
		}
	return null;
	}

// ===================================================================
//End of Date Functions

fnSetCurrDate();
