function ShippingEst(){ this.productID = ""; this.coundownTimerInterval = 0; this.serverTimeStamp = ""; this.startTimeStampOfLocalMachine = ""; this.currentlySelectedShipping = ""; this.shippingOptionsArr = new Array(); this.deliveryEstResponseEventsFunctionsArr = new Array(); this.deliveryEstResponseEventsObjectsArr = new Array(); this.deliveryEstCriticalErrorEventsFunctionsArr = new Array(); this.deliveryEstCriticalErrorEventsObjectsArr = new Array(); this.updateCountdownTimerEventsFunctionsArr = new Array(); this.updateCountdownTimerEventsObjectsArr = new Array();}
ShippingEst.prototype.selectNewShippingMethod = function(shippingMethodName)
{ this.currentlySelectedShipping = shippingMethodName; this.coundownTimerInterval_private();}
ShippingEst.prototype.countdownTimerEvnt = function(functionRef, objectRef)
{ this.updateCountdownTimerEventsFunctionsArr.push(functionRef); this.updateCountdownTimerEventsObjectsArr.push(objectRef);}
ShippingEst.prototype.responseEvnt = function(functionRef, objectRef)
{ this.deliveryEstResponseEventsFunctionsArr.push(functionRef); this.deliveryEstResponseEventsObjectsArr.push(objectRef);}
ShippingEst.prototype.attachErrorEvent = function(functionRef, objectRef)
{ this.deliveryEstCriticalErrorEventsFunctionsArr.push(functionRef); this.deliveryEstCriticalErrorEventsObjectsArr.push(objectRef);}
ShippingEst.prototype.setProductID = function(productID)
{ this.productID = productID;}
ShippingEst.prototype.getProductID = function()
{ return this.productID;}
ShippingEst.prototype.fireRequest = function()
{ if(this.productID == ""){ alert("You must set a Product ID first"); return;}
var instance = this; var dateObj = new Date(); var apiRequestURL = "./time_estimates_xml.php?productid=" + this.productID; var xmlHttpObjFromGlobalQueue = getXmlHttpObj("DeliveryEstXML"); if(xmlHttpObjFromGlobalQueue == null)
return; xmlHttpObjFromGlobalQueue.open('GET', apiRequestURL, true); xmlHttpObjFromGlobalQueue.onreadystatechange = function()
{ for(var t=0; t<xmlReqsObjArr.length; t++){ if(xmlReqsObjArr[t].reqObjFree || xmlReqsObjArr[t].reqObjParsing || xmlReqsObjArr[t].xmlHttpObj.readyState != 4 || xmlReqsObjArr[t].callBackFunctionName != "DeliveryEstXML")
continue; if(xmlReqsObjArr[t].xmlHttpObj.status == "200"){ xmlReqsObjArr[t].reqObjParsing = true; instance.parseXMLresponse(xmlReqsObjArr[t].xmlHttpObj.responseText);}
else{ instance.errorEvent_private(xmlReqsObjArr[t].xmlHttpObj.status, xmlReqsObjArr[t].xmlHttpObj.statusText);}
xmlReqsObjArr[t].reqObjFree = true; xmlReqsObjArr[t].reqObjParsing = false;}
}
xmlHttpObjFromGlobalQueue.send(null);}
ShippingEst.prototype.parseXMLresponse = function(xmlhttpresponseText)
{ var matchArr = xmlhttpresponseText.match(/\<now\>(\d+)\<\/now\>/); if(!matchArr){ this.errorEvent_private("5921", "No response from server."); return;}
this.serverTimeStamp = matchArr[1]; this.startTimeStampOfLocalMachine = Math.round(new Date().getTime()/1000.0); var shippingOptionsCounter = -1; var xmlLinesArr = xmlhttpresponseText.split("\n"); for(var lineNo = 0; lineNo < xmlLinesArr.length; lineNo++)
{ if(xmlLinesArr[lineNo].toString().match(/\<shipping\>/)){ shippingOptionsCounter++; this.shippingOptionsArr[shippingOptionsCounter] = new ShippingOption();}
else if(xmlLinesArr[lineNo].toString().match(/\<method\>/)){ this.shippingOptionsArr[shippingOptionsCounter].shippingOptionName = getXMLdata(xmlLinesArr[lineNo]); if(this.currentlySelectedShipping == "")
this.currentlySelectedShipping = this.shippingOptionsArr[shippingOptionsCounter].shippingOptionName;}
else if(xmlLinesArr[lineNo].toString().match(/\<arrival\>/)){ this.shippingOptionsArr[shippingOptionsCounter].arrivalDesc = getXMLdata(xmlLinesArr[lineNo]);}
else if(xmlLinesArr[lineNo].toString().match(/\<arrival_date\>/)){ this.shippingOptionsArr[shippingOptionsCounter].arrivalDate = getXMLdata(xmlLinesArr[lineNo]);}
else if(xmlLinesArr[lineNo].toString().match(/\<ship\>/)){ this.shippingOptionsArr[shippingOptionsCounter].shipDate = getXMLdata(xmlLinesArr[lineNo]);}
else if(xmlLinesArr[lineNo].toString().match(/\<cutoff\>/)){ this.shippingOptionsArr[shippingOptionsCounter].cutOffTimeStamp = getXMLdata(xmlLinesArr[lineNo]);}
}
for(var i=0; i < this.deliveryEstResponseEventsFunctionsArr.length; i++){ this.deliveryEstResponseEventsFunctionsArr[i].call(this.deliveryEstResponseEventsObjectsArr[i]);}
this.coundownTimerInterval_private(); var instanceForThis = this; this.coundownTimerInterval = setInterval ( function() { instanceForThis.coundownTimerInterval_private();}, 1000 );}
ShippingEst.prototype.earliestDelivery = function()
{ var earliestDate = ""; for(var i=0; i<this.shippingOptionsArr.length; i++){ if(earliestDate == ""){ earliestDate = this.shippingOptionsArr[i].arrivalDate; continue;}
var dateOfThisMethod = Date.parse(this.shippingOptionsArr[i].arrivalDate); var dateOfEarliest = Date.parse(earliestDate); if(dateOfThisMethod < dateOfEarliest){ earliestDate = this.shippingOptionsArr[i].arrivalDate;}
}
return earliestDate;}
ShippingEst.prototype.errorEvent_private = function(responseCode, responseError)
{ for(var i=0; i < this.deliveryEstCriticalErrorEventsFunctionsArr.length; i++){ this.deliveryEstCriticalErrorEventsFunctionsArr[i].call(this.deliveryEstCriticalErrorEventsObjectsArr[i], responseCode, responseError);}
}
ShippingEst.prototype.coundownTimerInterval_private = function()
{ var currentCutoffTimestamp = 0; for(var i=0; i<this.shippingOptionsArr.length; i++){ if(this.shippingOptionsArr[i].shippingOptionName == this.currentlySelectedShipping){ currentCutoffTimestamp = this.shippingOptionsArr[i].cutOffTimeStamp; break;}
}
if(currentCutoffTimestamp == 0)
{ alert("Error getting the shipping cutoff timestamp");}
var timeDifferenceBetweenLocalAndRemote = this.serverTimeStamp - this.startTimeStampOfLocalMachine; var currentTimeStampOfServer = Math.round(new Date().getTime()/1000.0) + timeDifferenceBetweenLocalAndRemote; var secondsLeftUntilDeadline = (currentCutoffTimestamp - currentTimeStampOfServer); if(secondsLeftUntilDeadline < 0)
{ var hours = "0"; var minutes = "00"; var seconds = "00";}
else{ var hours = Math.floor((secondsLeftUntilDeadline / (60 * 60))); var numberOfSecondsWithoutHours = secondsLeftUntilDeadline - (60 * 60 * hours); var minutes = Math.floor(numberOfSecondsWithoutHours / 60); var seconds = secondsLeftUntilDeadline - (60 * 60 * hours) - (60 * minutes); hours = hours + ""; minutes = minutes + ""; seconds = seconds + ""; if(minutes.length == 1)
minutes = "0" + minutes; if(seconds.length == 1)
seconds = "0" + seconds;}
for(var i=0; i < this.updateCountdownTimerEventsFunctionsArr.length; i++){ this.updateCountdownTimerEventsFunctionsArr[i].call(this.updateCountdownTimerEventsObjectsArr[i], hours, minutes, seconds);}
}
ShippingEst.prototype.getLowestPriorityMethodWhichArrivesByDate = function(arrivalDateObj)
{ var lastAvailableShippingMethod = ""; for(var i=0; i<this.shippingOptionsArr.length; i++){ var dateOfThisMethod = Date.parse(this.shippingOptionsArr[i].arrivalDate); var requiredArrivalDate = arrivalDateObj.getTime(); dateOfThisMethod -= 5000; if(dateOfThisMethod < requiredArrivalDate){ lastAvailableShippingMethod = this.shippingOptionsArr[i].shippingOptionName;}
}
return lastAvailableShippingMethod;}
function ShippingOption(){ this.shippingOptionName = ""; this.cutOffTimeStamp = ""; this.arrivalDesc = ""; this.arrivalDate = ""; this.shipDate = "";}

