/*
 * StandardEngine.js - Standard Quote Engine
 * Written by AMaitland
 * Version 1.1
 */

//Standard quote AJAX call return
function standardCalculate(response)
{
	var xmldoc = response.responseXML.documentElement;

	var items = xmldoc.getElementsByTagName("PREMIUM");
	for(var i = 0; i < items.length; i++)
	{
		var attr = items[i].attributes;
		var id = parseInt(attr[0].nodeValue, 10);
		var amount = attr[1].nodeValue;
		var destination = attr[2].nodeValue;
		var planControl = findPlanControlById(_planControlArray, id);
		planControl.setDestination(destination);
		planControl.setPremium(amount);
	}
	$('imgArrowProcessing').hide();
	$('imgArrowStatic').show();
};

function findPlanControlById(controlArray, id)
{
  for(var i = 0; i < controlArray.length; i++)
	{
	  if(controlArray[i].PlanID == id)
	  {
	    return controlArray[i];
	  }
	}
	return null;
}

function TrackEvent(category, action, optional_label, optional_value)
{
	if (_gaq != null)
	{
		_gaq.push(['_trackEvent', category, action, optional_label, optional_value]);
	}
}

function standardTimeout()
{
	_errorDisplayControlStandard.AppendAndDisplay("Your quote request timed out, please try again.");
	$('imgArrowProcessing').hide();
	$('imgArrowStatic').show();
}

function standardQuote(quoteControl, quoteService)
{
	var quote = quoteControl.getQuote();

	try
	{
		var startDate = new Mondial.SimpleDate().ParseString(quote.StartDate).GetDate();
		var endDate = new Mondial.SimpleDate().ParseString(quote.EndDate).GetDate();
		var diff = (endDate - startDate) / 1000;
		var one_day_epoch = 24 * 60 * 60;
		var d = Math.round((diff / one_day_epoch) + 1);

		TrackEvent("HomePage", "DynamicQuote", "A=" + quote.Adults + ";C=" + quote.Dependants + ";D=" + quote.Destination, d);
	}
	catch (e)
	{
	}

	quoteService.Submit(quote.Adults, quote.Dependants, quote.Destination, quote.StartDate, quote.EndDate, _plans);
}

function escapeHTML(str)
{
   var div = document.createElement('div');
   var text = document.createTextNode(str);
   div.appendChild(text);
   return div.innerHTML;
}; 

function getCookieDate(firstDate, secondDate, today)
{
	var dteStart = new Mondial.SimpleDate().ParseString(secondDate);
	
	if(!dteStart.IsGreater(new Mondial.SimpleDate().ParseString(today).ToString()))
	{
		return firstDate;
	}
	
	return secondDate;
}

function cbStandardQuoteChange(o)
{
	$('imgArrowStatic').hide();
	$('imgArrowProcessing').show();

	standardQuote(_quoteControl, _standardQuoteService);
	var quote = _quoteControl.getQuote();
	for (var i = 0; i < _planControlArray.length; i++)
	{
		_planControlArray[i].setDestination(quote.Destination);
		// put the selected destination into each element of the plan control array
		_planControlArray[i].NewDestination = quote.Destination;
	}

	_errorDisplayControlStandard.Hide();
	var isBasicValid = _basicValidator.Validate();
	if(isBasicValid)
	{
		var errors = new Array();
		var noOfErrors = 0;
		for(var i = 0; i < _planControlArray.length; i++)
		{
			var validator = _planControlArray[i].getValidator(_quoteControl, _today, _todayPlusOneYear, _todayPlusTwoYear);
			var isValid = validator.Validate();
			if(!isValid)
			{
				noOfErrors = noOfErrors + 1;
				errors.push(_planControlArray[i].SelectedPlan.Description + ": " + validator.ValidateMessage);
			}
		}
		if(noOfErrors < _planControlArray.length)
		{
			//standardQuote(_quoteControl, _standardQuoteService);
			if(noOfErrors != 0)
			{
				_errorDisplayControlStandard.AppendAndDisplayWarning(errors);
			}
		}
		else
		{
			_errorDisplayControlStandard.AppendAndDisplay(errors);
		}
	}
	else 
	{
		_errorDisplayControlStandard.AppendAndDisplay(_basicValidator.ValidateMessage);
	}
}

function onChange_EndMonthYear(evt)
{
	var endDate = Event.element(evt).value;
	_quoteControl.EndDate.updateDays(endDate);
	evt.stop();
}

function onChange_StartMonthYear(evt)
{
	var startDate = Event.element(evt).value;
	_quoteControl.StartDate.updateDays(startDate);
	_quoteControl.EndDate.resetEndDates(_arrEndDates);
	evt.stop();
}

function IsDomestic(destination)
{
  if(destination.toUpperCase() == 'NEW ZEALAND')
  {
    return true;
  }
  return false;
}

function escapeHTML(str)
{
   var div = document.createElement('div');
   var text = document.createTextNode(str);
   div.appendChild(text);
   return div.innerHTML;
}; 

function getCookieDate(firstDate, secondDate, today)
{
	var dteStart = new Mondial.SimpleDate().ParseString(secondDate);
	
	if(!dteStart.IsGreater(new Mondial.SimpleDate().ParseString(today).ToString()))
	{
		return firstDate;
	}
	
	return secondDate;
}

/*
 * SABLib.js - Select a Benefit Quoting Engine
 * Written by AMaitland
 * Version 1.1
 */
 
Mondial =
{
	//Standard Mode (Multi Quote)
	QUOTE_MODE_STANDARD : 0,
	//Select a Benefit Mode
	QUOTE_MODE_SAB : 1,
	SAB_COOKIE_NAME : "worldcareSABCookie",
	IEBrowserVersion : parseFloat(navigator.appVersion.split('MSIE')[1]),
	//TODO: tidy up some of this
	Browser:
	{
		IEBrowserVersion : parseInt(navigator.appVersion.split('MSIE')[1], 10),
		IE6 : parseInt(navigator.appVersion.split('MSIE')[1], 10) == 6
	},
	ApplyPNGFix : ((this.IEBrowserVersion >= 5.5) && (this.IEBrowserVersion < 7) && (document.body.filters)),
	//Create Mondial.Ajax namespace
	Ajax : {},
	MapTimeUnit : function(unit)
	{
	  var unitInt = parseInt(unit, 10);
	  if(unitInt == 0)
	  {
	    return "Day";
	  }
	  if(unitInt == 1)
	  {
	    return "Month";
	  }
	  //Default Return of "Year"
	  return "Year";
	}
};

Mondial.BasicValidator = Class.create(
{
	ValidateMessage : "OK",
	StartDate : null,
	EndDate : null,
	Today : null,
	PurchaseCutOff : null,
	TodayPlusTwoYears : null,
	
	initialize : function(dmyStartDate, dmyEndDate, sdToday, sdPurchaseCutOff, todayPlusTwoYears)
	{
		this.StartDate = dmyStartDate;
		this.EndDate = dmyEndDate;
		this.Today = sdToday;
		this.PurchaseCutOff = sdPurchaseCutOff;
		this.TodayPlusTwoYears = todayPlusTwoYears;
	},
	IsStartDateValid : function ()
	{
		//Validate start date
		var dteStart = this.StartDate.GetSimpleDate();
		var dteEnd = this.EndDate.GetSimpleDate();
		dteStart.MinRange = this.Today.ToString();
		dteStart.MaxRange = this.PurchaseCutOff.ToString();
		
		if(!dteStart.IsGreater(this.Today.ToString()))
		{
			this.ValidateMessage = "Start date is invalid. Earliest possible start date is " + this.Today.ToString();
			return false;
		}
		if(!dteStart.IsInRange())
		{
			this.ValidateMessage = "Start date is invalid. Policys start dates must be between " + this.Today.ToString() + " and " + dteStart.MaxRange;
			return false;
		}
		
		return true;
	},
	IsEndDateValid : function ()
	{
		//Validate end date
		var dteStart = this.StartDate.GetSimpleDate();
		var dteEnd = this.EndDate.GetSimpleDate();
		dteEnd.MinRange = this.Today.ToString();
		dteEnd.MaxRange = this.TodayPlusTwoYears.ToString();
		
		if(!dteEnd.IsInRange())
		{
			this.ValidateMessage = "End date is invalid. Policys end dates must be between " + this.Today.ToString() + " and " + dteEnd.MaxRange;
			return false;
		}
		if(!dteEnd.IsGreater(dteStart.ToString()))
		{
			this.ValidateMessage = "End date is invalid. End date must come after the start date.";
			return false;
		}
		
		return true;	
	},
	Validate : function ()
	{
		this.ValidateMessage = "OK";
		
		return this.IsStartDateValid() && this.IsEndDateValid();
	}
});

Mondial.QuoteValidator = Class.create(
{
	StartDate: null,
	EndDate: null,
	ValidateMessage: "OK",
	Today: null,
	PurchaseCutOff: null,
	MaxLength: null,
	MaxLengthUnit: null,
	TodayPlusTwoYears: null,

	initialize: function(dmyStartDate, dmyEndDate, sdToday, sdPurchaseCutOff, todayPlusTwoYears, intMaxLength, strMaxLengthUnit) {
		this.StartDate = dmyStartDate;
		this.EndDate = dmyEndDate;
		this.Today = sdToday;
		this.PurchaseCutOff = sdPurchaseCutOff;
		this.MaxLength = parseInt(intMaxLength, 10);
		this.MaxLengthUnit = strMaxLengthUnit;
		this.TodayPlusTwoYears = todayPlusTwoYears;
	},
	IsStartDateValid: function() {
		//Validate start date
		var dteStart = this.StartDate.GetSimpleDate();
		var dteEnd = this.EndDate.GetSimpleDate();
		dteStart.MinRange = this.Today.ToString();
		dteStart.MaxRange = this.PurchaseCutOff.ToString();

		if (!dteStart.IsGreater(this.Today.ToString())) {
			this.ValidateMessage = "Start date is invalid. Earliest possible start date is " + this.Today.ToString();
			return false;
		}
		if (!dteStart.IsInRange()) {
			this.ValidateMessage = "Start date is invalid. Policys start dates must be between " + this.Today.ToString() + " and " + dteStart.MaxRange;
			return false;
		}

		return true;
	},
	IsEndDateValid: function() {
		//Validate end date
		var dteStart = this.StartDate.GetSimpleDate();
		var dteEnd = this.EndDate.GetSimpleDate();
		dteEnd.MinRange = this.Today.ToString();
		dteEnd.MaxRange = this.TodayPlusTwoYears.ToString();

		if (!dteEnd.IsInRange()) {
			this.ValidateMessage = "End date is invalid. Policys end dates must be between " + this.Today.ToString() + " and " + dteEnd.MaxRange;
			return false;
		}
		if (!dteEnd.IsGreater(dteStart.ToString())) {
			this.ValidateMessage = "End date is invalid. End date must come after the start date.";
			return false;
		}

		if (!this.ValidateMaxLength(this.MaxLength, this.MaxLengthUnit)) {
			this.ValidateMessage = "Policy Length cannot exceed " + this.MaxLength + " " + this.MaxLengthUnit + "(s)";
			return false;
		}

		return true;
	},
	ValidateMaxLength: function() {
		var dteStartDate = this.StartDate.GetSimpleDate().GetDate();
		var dteEndDate = this.EndDate.GetSimpleDate().GetDate();

		var syear = 0;
		var unit = this.MaxLengthUnit.toLowerCase();

		if (/year/.test(unit)) {
			// add number of years and then turn into a date
			syear = parseInt(dteStartDate.getFullYear(), 10) + parseInt(this.MaxLength, 10);
			dteStartDate.setYear(syear);
		}
		else if (/month/.test(unit)) {
			smonth = parseInt(dteStartDate.Month, 10) + parseInt(this.MaxLength, 10);
			if (smonth > 12) {
				smonth = parseInt(smonth, 10) - 12;
				syear = parseInt(syear, 10) + 1;
			}

			dteStartDate.setMonth(smonth - 1);
		}
		else if (/day/.test(unit)) {
			var length = parseInt(this.MaxLength, 10) - 1;
			dteStartDate.setDate(dteStartDate.getDate() + length);
		}

		if (dteEndDate.getTime() >= dteStartDate.getTime()) {
			return false;
		}
		else {
			return true;
		}
	},
	Validate: function() {
		this.ValidateMessage = "OK";

		return this.IsStartDateValid() && this.IsEndDateValid();
	}
});

Mondial.DMYControl = Class.create(
{
  /// <summary>
	/// DMYControl - Represents a Two Part Date Control (Day and Month+Year)
	/// Both the Day control and Month+Year controls MUST be dropdown's
	/// </summary>
	/// <param name="ddDay">The day drop down list</param>
	/// <param name="ddMonthYear">The Month+Year drop down list</param>
	/// <param name="strInitialDate">The initial date in string format (dd/MM/yyyy)</param>
  initialize : function(ddDay, ddMonthYear, strInitialDate)
	{
		this.DDDay = $(ddDay);
		this.DDMonthYear = $(ddMonthYear);
		this.InitialDate = strInitialDate;
		var dte = new Mondial.SimpleDate().ParseString(strInitialDate);
		this.updateMonthOnLoad(dte.ToMonthYearStr(), dte.Day);
	},
	GetSimpleDate : function ()
	{
		return new Mondial.SimpleDate().ParseTwoPartDate(this.DDDay.value, this.DDMonthYear.value);
	},
	updateDate : function (strDate)
	{
		var dte = new Mondial.SimpleDate().ParseString(strDate);
		var strMonthYear = dte.ToMonthYearStr();
		
		for(var i = 0; i < this.DDDay.options.length; i++)
		{
			if(parseInt(this.DDDay.options[i].value, 10) == dte.Day)
			{
				this.DDDay.options[i].selected = true;
			}
		}
		
		for(var i = 0; i < this.DDMonthYear.options.length; i++)
		{
			if(this.DDMonthYear.options[i].value == strMonthYear)
			{
				this.DDMonthYear.options[i].selected = true;
			}
		}
	},
	updateMonthOnLoad : function (strMonthYear, strDay)
	{
		var dte = new Mondial.SimpleDate().ParseString("01/" + strMonthYear);
		
		var intDaysInMonth;
		
		try
		{
			intDaysInMonth = dte.DaysInMonth();
		}
		catch (err)
		{
			//Ignore this error
		}
		
		//Check to see if days in month is ok.
		if(intDaysInMonth >= 28)
		{
			var dteCurrent = new Mondial.SimpleDate().Now();
			var dte = dteCurrent.ToMonthYearStr();
			var avaliableDays = intDaysInMonth - dteCurrent.Day;
			
			//If the month is the current, the remove all past dates and adjust
			// number of days in month
			if(strMonthYear == dte)
			{
				if(intDaysInMonth < this.DDMonthYear.options.length)
				{
					while(this.DDMonthYear.options.length > intDaysInMonth)
					{
						this.removeSelectElement(ddControl, ddControl.length - 1);
					}
				}
			}
		}
		
		this.updateDate(this.InitialDate);
	},
	//Wrapper function around the remove, incase we need to implement some backwards compatable functions
	removeSelectElement : function (dd, intIndex)
	{
		dd.removeChild(dd.options[intIndex]);			
	},
	updateDays : function(strMonthYear)
	{
		var ddControl = $(this.DDDay);
		var dte = new Mondial.SimpleDate().ParseString("01/" + strMonthYear);
		
		var intDaysInMonth;
		
		try
		{
			intDaysInMonth = dte.DaysInMonth();
		}
		catch (err)
		{
			//Ignore this error
		}
		
		//Check to see if days in month is ok.
		if(intDaysInMonth >= 28)
		{
			var dteCurrent = new Mondial.SimpleDate().Now();
			var avaliableDays = intDaysInMonth - dteCurrent.Day + 1;
			
			//If the month is the current, the remove all past dates and adjust
			// number of days in month
			if(strMonthYear == dteCurrent.ToMonthYearStr())
			{
				if(ddControl.length < intDaysInMonth)
				{
					while(parseInt((ddControl.options[ddControl.length - 1].value), 10) != intDaysInMonth)
					{
						var intVal = parseInt((ddControl.options[ddControl.length - 1].value), 10) + 1;
						this.createAppendOption(ddControl, intVal);
					}
				}
				
				if(intDaysInMonth < ddControl.length)
				{
					while(ddControl.length > intDaysInMonth)
					{
						this.removeSelectElement(ddControl, ddControl.length - 1);
					}
				}
				
				if(ddControl.length > avaliableDays)
				{
					while(ddControl.length > avaliableDays)
					{
						this.removeSelectElement(ddControl, 0);
					}
				}
			}
			else
			{
				while(parseInt((ddControl.options[0].value), 10) != 1)
				{
					var op = document.createElement("option");
					var intVal = parseInt((ddControl.options[0].value), 10) - 1;
					op.innerHTML = intVal;
					op.value = intVal;
					ddControl.insertBefore(op, ddControl.options[0]);
				}
				
				if(intDaysInMonth < ddControl.length)
				{
					while(ddControl.length > intDaysInMonth)
					{
						this.removeSelectElement(ddControl, ddControl.length - 1);
					}
				}
				else
				{
					while(ddControl.length < intDaysInMonth)
					{
						var intVal = parseInt((ddControl.options[ddControl.length - 1].value), 10) + 1;
						this.createAppendOption(ddControl, intVal);
					}
				}
			}
		}
	},
	createAppendOption : function(ddParent, val)
	{
		var op = document.createElement("option");
		op.innerHTML = val;
		op.value = val;
		ddParent.appendChild(op);
	},
	updateEndDates : function (arrDates, intIndex)
	{
		this.resetEndDates(arrDates);
		
		for(var i = 0; i < intIndex; i++)
		{
			this.DDMonthYear.removeChild(this.DDMonthYear.options[0]);
		}
		
		var intTotal = 13;
		if(this.DDMonthYear.options.length == 12)
		{
			intTotal = 12;
		}
		
		while(this.DDMonthYear.options.length > intTotal)
		{
			this.DDMonthYear.removeChild(this.DDMonthYear.options[this.DDMonthYear.options.length - 1]);
		}
	},
	resetEndDates : function (arrDates)
	{
		if(this.DDMonthYear.options.length < arrDates.length)
		{
			var matchFound = false;
		
			for(var i = 0; i < arrDates.length; i++)
			{
				if(arrDates[i] != this.DDMonthYear.options[0] && !matchFound)
				{
					this.DDMonthYear.insertBefore(arrDates[i], this.DDMonthYear.options[i]);
				}
				else if(arrDates[i] != this.DDMonthYear.options[0])
				{
					this.DDMonthYear.appendChild(arrDates[i]);
				}
			}
		
			var intCount = arrDates.length - this.DDMonthYear.options.length;
			for(var i = intCount; i >= 0; i--)
			{
				this.DDMonthYear.insertBefore(arrDates[i], this.DDMonthYear.options[0]);
			}
		}
	}
});

Mondial.SimpleDate = Class.create(
{
	MaxRange : 0,
	MinRange : 0,
	initialize : function(intDay, intMonth, intYear)
	{
		this.Day = intDay;
		this.Month = intMonth;
		this.Year = intYear;
	},
	Now : function ()
	{
		var dteCurrent = new Date();
		dteCurrent.setDate(dteCurrent.getDate());
		
		return this.ParseDate(dteCurrent);
	},
	ToMonthYearStr : function()
	{
		return this.padDate(this.Month) + "/" + this.Year;
	},
	GetDate : function()
	{
		//JS Month starts from 0-11
		return new Date(this.Year, parseInt(this.Month - 1, 10), this.Day);
	},
	padDate : function (intInput)
	{
		if(intInput < 10)
		{
			intInput = "0" + intInput;
		}
		return intInput;
	},	
	ParseTwoPartDate : function(strDay, strMonthYear)
	{
		var intIndex = strMonthYear.indexOf("/");
		this.Day = parseInt(strDay, 10);
		this.Month = parseInt(strMonthYear.substring(0, intIndex), 10);
		this.Year = parseInt(strMonthYear.substring(intIndex + 1), 10);
		
		return this;
	},
	ParseMonthYear : function(strMonthYear)
	{
		var intIndex = strMonthYear.indexOf("/");
		this.Day = 1;
		this.Month = parseInt(strMonthYear.substring(0, intIndex), 10);
		this.Year = parseInt(strMonthYear.substring(intIndex + 1), 10);		
	},
	ParseString : function(strDayMonthYear)
	{
		var dtCh = "/";
		var pos1 = strDayMonthYear.indexOf(dtCh);
		var pos2 = strDayMonthYear.indexOf(dtCh, pos1+1);
		this.Day = parseInt(strDayMonthYear.substring(0, pos1), 10);
		this.Month = parseInt(strDayMonthYear.substring(pos1+1, pos2), 10);
		this.Year = parseInt(strDayMonthYear.substring(pos2+1), 10);
		
		return this;
	},
	ParseDate : function(jsdate)
	{
		this.Day  = jsdate.getDate();
		this.Month = jsdate.getMonth() + 1;
		this.Year  = parseInt(jsdate.getFullYear(), 10);
		
		return this;
	},
	DaysInMonth : function()
	{
		var dd = new Date(this.Year, this.Month, 0);
		return dd.getDate();
	},
	//Is the current date between MinRange and MaxRange
	IsInRange : function()
	{
		if(this.MinRange == null && this.MaxRange == null)
		{
			return true;
		}
		else
		{
			if (this.MinRange == null || this.MinRange == "")
			{
				this.MinRange = 0;
			}
			
			if (this.MaxRange == null || this.MaxRange == "")
			{
				this.MaxRange = 0;
			}

			var intVal = this.convertToInt(this);
	    var intMinOp = this.MinRange == 0 ? 0 : this.convertToInt(new Mondial.SimpleDate().ParseString(this.MinRange));
	    var intMaxOp = this.MaxRange == 0 ? 0 : this.convertToInt(new Mondial.SimpleDate().ParseString(this.MaxRange));
			
			return (intVal >= intMinOp) && (intVal <= intMaxOp);
		}
	},
	//Is given date greater than current SimpleDate
	IsGreater : function (strDate2)
	{
		var intDate1 = this.convertToInt(this);
		var intDate2 = this.convertToInt(new Mondial.SimpleDate().ParseString(strDate2));

		return (intDate1 >= intDate2);
	},
	GetFullYear : function(year, century, cutoffyear)
	{
		return (year + parseInt(century)) - ((year < cutoffyear) ? 0 : 100);
	},
	convertToInt : function (simpleDate)
	{
		return simpleDate.GetDate().valueOf();
	},
	//Outputs the simple date in the format dd/MM/yyyy
	ToString : function()
	{
		return this.padDate(this.Day) + "/" + this.padDate(this.Month) + "/" + this.Year;
	}
});

Mondial.Quote = Class.create(
{
	Adults : 1,
	Dependants : 0,
	Destination : "WORLDWIDE",
	StartDate : "",
	EndDate : "",
	Selection : "",
	
	///Prototype Init Function - Called when object created
	initialize : function()
	{

	}
});

Mondial.QuoteCookie = Class.create(Mondial.Quote,
{
	Mode : Mondial.QUOTE_MODE_SAB,
	SliderState : null,
	initialize: function($super, quote)
	{
    $super();
    if(quote != null)
    {
			this.Update(quote);	
		}
  },
  Update : function (quote)
  {
		this.Adults = quote.Adults;
		this.Dependants = quote.Dependants;
		this.Destination = quote.Destination;
		this.StartDate = quote.StartDate;
		this.EndDate = quote.EndDate;
		if(quote.Selection != null && quote.Selection != "")
		{
			this.Selection = quote.Selection;
		}
		if(quote.Mode != null)
		{
			this.Mode = quote.Mode;
		}
		if(quote.SliderState != null)
		{
			this.SliderState = quote.SliderState;
		}
  }  
});

Mondial.PlanControl = Class.create(
{
	SelectedPlan: null,
	Destination: "",
	Premium: 0.00,
	BenefitsLinkUrl: "",
	ChildPlanId: 0,
	Destination: "WORLDWIDE",
	Blurb: "",
	OnBuyClick: null,

	///Prototype Init Function - Called when object created
	initialize: function(masterPlan, destination) {
		this.Id = "planControl" + masterPlan.Id;
		this.MasterPlan = masterPlan;
		this.PlanID = masterPlan.Id;
		this.Destination = destination;

		this.BenefitsLinkUrl = this.MasterPlan.AvaliablePlans[0].BenefitsLink + "?mode=inline";

		this.PremiumDiv = $(this.Id + "_premiumDiv");
		this.BlurbDiv = $(this.Id + "_blurbDiv");
		this.NameDiv = $(this.Id + "_nameDiv");
		this.BenefitsLink = $(this.Id + "_benefitsLink");
		this.BuyLink = $(this.Id + "_buyLink");
		this.BuyLinkDisabled = $(this.Id + "_buyLinkDisabled");
		this.MoreLink = $(this.Id + "_moreLink");
		this.MoreInfo = $(this.Id + "_moreInfo");
		this.NewDestination = destination;

		this.BuyLink.observe("click", this.buy_click.bind(this));
		this.setDestination(destination);
	},
	setPremium: function(premium) {
		if (premium == "0.00") {
			this.PremiumDiv.update("N/A");
			this.BuyLink.hide();
		}
		else if (IsDomestic(this.NewDestination) && this.SelectedPlan.Description.toUpperCase() == "BUDGET") {
			this.PremiumDiv.update("<span class='internationalOnly'>International Only</span>");
			this.BuyLink.hide();
			this.BuyLinkDisabled.show();
		}
		else {
			this.PremiumDiv.update("$" + premium);
			this.BuyLink.show();
			this.BuyLinkDisabled.hide();
		}
	},
	setDestination: function(destination) {
		this.Destination = destination;
		var masterPlan = this.MasterPlan;
		if (masterPlan.HasMultipleRegions) {
			this.SelectedPlan = this._findPlan(masterPlan, this.Destination);
		}
		else {
			this.SelectedPlan = masterPlan.AvaliablePlans[0];
		}
		this.NameDiv.update(this.SelectedPlan.Description);
		this.BlurbDiv.update(this.SelectedPlan.Blurb);
		this.BenefitsLink.href = this.SelectedPlan.BenefitsLink;
	},
	getValidator: function(quoteControl, today, todayPlusOneYear, todayPlusTwoYears) {
		return new Mondial.QuoteValidator(quoteControl.StartDate, quoteControl.EndDate, new Mondial.SimpleDate().ParseString(today), new Mondial.SimpleDate().ParseString(todayPlusOneYear), new Mondial.SimpleDate().ParseString(todayPlusTwoYears), this.SelectedPlan.Length.Value, Mondial.MapTimeUnit(this.SelectedPlan.Length.Unit));
	},
	setOnBuyClick: function(handler) {
		this.OnBuyClick = handler;
	},
	buy_click: function(e) {
		if (this.OnBuyClick != null) {
			this.OnBuyClick(e, this.MasterPlan.Id);
		}
	},
	setPlanId: function(planId) {
		this.ChildPlanId = planId;
	},
	_findPlan: function(masterPlan, destination) {
		for (var i = 0; i < masterPlan.AvaliablePlans.length; i++) {
			var childPlan = masterPlan.AvaliablePlans[i];
			for (var j = 0; j < childPlan.Destinations.length; j++) {
				if (childPlan.Destinations[j].Value.toUpperCase() == destination.toUpperCase()) {
					return childPlan;
				}
			}
		}

		return null;
	}
});

Mondial.QuoteControl = Class.create(
{
	//Reference to event handler functions
	OnDestinationChange : null,
	OnAdultsChange : null,
	OnChildrenChange : null,
	OnStartDateChange : null,
	OnEndDateChange : null,
		
	///Prototype Init Function - Called when object created
	initialize : function(destination, adults, children, startDay, startMonthYear, endDay, endMonthYear, startDate, endDate, initQuote)
	{
		//Controls
		this.Destination = $(destination);
		this.Adults = $(adults);
		this.Children = $(children);
		this.StartDay = $(startDay);
		this.StartMonthYear = $(startMonthYear);
		this.EndDay = $(endDay);
		this.EndMonthYear = $(endMonthYear);
		this.StartDate = new Mondial.DMYControl(startDay, startMonthYear, initQuote != null ? initQuote.StartDate : startDate);
		this.EndDate = new Mondial.DMYControl(endDay, endMonthYear, initQuote != null ? initQuote.EndDate : endDate);
		this.InitialQuote = initQuote;
	},
	getQuote : function()
	{
		var quote = new Mondial.Quote();
		
		quote.Destination = this.Destination.options[this.Destination.selectedIndex == -1 ? 0 : this.Destination.selectedIndex].value;
		quote.Adults = this.Adults.options[this.Adults.selectedIndex == -1 ? 0 : this.Adults.selectedIndex].value;
		quote.Dependants = this.Children.options[this.Children.selectedIndex == -1 ? 0 : this.Children.selectedIndex].value;
		quote.StartDate = this.StartDay.value + '/' + this.StartMonthYear.value;
		quote.EndDate = this.EndDay.value + '/' +  this.EndMonthYear.value;

		 return quote;
	},
	loadStandard : function(masterPlans)
	{
		var dest = null;
		var adult = null;
		var child = null;
		if(this.Destination.options.length > 0)
		{
			dest = this.Destination.options[this.Destination.selectedIndex == -1 ? 0 : this.Destination.selectedIndex].value;
		}
		else
		{
			dest = this.InitialQuote.Destination;
		}
		if(this.Adults.options.length > 0)
		{
			adult = this.Adults.options[this.Adults.selectedIndex == -1 ? 0 : this.Adults.selectedIndex].value;
		}
		else
		{
			adult = this.InitialQuote.Adults;
		}
		if(this.Children.options.length > 0)
		{
			child = this.Children.options[this.Children.selectedIndex == -1 ? 0 : this.Children.selectedIndex].value;
		}
		else
		{
			child = this.InitialQuote.Dependants;
		}
		
		var maxAdults = masterPlans[0].MaxAdults;
		var maxDependants = masterPlans[0].MaxDependants;
		
		this.Adults.options.length = 0;
		this.Children.options.length = 0;
		
		for (var i = 0; i < maxAdults; i++)
		{
			this.Adults.options[i] = new Option(i + 1, i + 1);
		}
		for (var i = 0; i <= maxDependants; i++)
		{
			this.Children.options[i] = new Option(i, i);
		}
		this.Destination.options.length = 0;	// clear list box
		var regions = masterPlans[0].AvaliableDestinations;
		for (i = 0; i < regions.length; i++)
		{
			this.Destination.options[i] = new Option(regions[i].Description, regions[i].Value);
		}
		
		if(dest != null)
		{
			this.setDestination(dest);
		}
		
		if(adult != null)
		{
			this.setAdult(adult);
		}
		
		if(child != null)
		{
			this.setChild(child);
		}
	},
	clearEvents : function()
	{
		if(this.OnDestinationChange != null) Event.stopObserving(this.Destination, "change", this.OnDestinationChange);
		if(this.OnAdultsChange != null) Event.stopObserving(this.Adults, "change", this.OnAdultsChange);
		if(this.OnChildrenChange != null) Event.stopObserving(this.Children, "change", this.OnChildrenChange);
		if(this.OnStartDateChange != null) Event.stopObserving(this.StartDay, "change", this.OnStartDateChange);
		if(this.OnStartDateChange != null) Event.stopObserving(this.StartMonthYear, "change", this.OnStartDateChange);
		if(this.OnEndDateChange != null) Event.stopObserving(this.EndDay, "change", this.OnEndDateChange);
		if(this.OnEndDateChange != null) Event.stopObserving(this.EndMonthYear, "change", this.OnEndDateChange);
		
	},
	//Clears controls (does not clear start and end date)
	clearControls : function()
	{
		this.Destination.options.length = 0;
		this.Adults.options.length = 0;
		this.Children.options.length = 0;
	},
	setOnDestinationChange : function(handler)
	{
		if(this.OnDestinationChange != null)
		{
			Event.stopObserving(this.Destination, "change", this.OnDestinationChange);
		}
		this.OnDestinationChange = handler;		
		this.Destination.observe("change", handler);
	},
	setOnAdultsChange : function(handler)
	{
		if(this.OnAdultsChange != null)
		{
			Event.stopObserving(this.Adults, "change", this.OnAdultsChange);
		}
		this.OnAdultsChange = handler;		
		this.Adults.observe("change", handler);
	},
	setOnChildrenChange : function(handler)
	{
		if(this.OnChildrenChange != null)
		{
			Event.stopObserving(this.Children, "change", this.OnChildrenChange);
		}
		this.OnChildrenChange = handler;		
		this.Children.observe("change", handler);
	},
	setOnStartDateChange : function(handler)
	{
		if(this.OnStartDateChange != null)
		{
			Event.stopObserving(this.StartDay, "change", this.OnStartDateChange);
			Event.stopObserving(this.StartMonthYear, "change", this.OnStartDateChange);
		}
		this.OnStartDateChange = handler;		
		this.StartDay.observe("change", handler);
		this.StartMonthYear.observe("change", handler);
	},
	setOnEndDateChange : function(handler)
	{
		if(this.OnEndDateChange != null)
		{
			Event.stopObserving(this.EndDay, "change", this.OnEndDateChange);
			Event.stopObserving(this.EndMonthYear, "change", this.OnEndDateChange);
		}
		this.OnEndDateChange = handler;
		this.EndDay.observe("change", handler);
		this.EndMonthYear.observe("change", handler);
	},
	setAdult : function(selected)
	{
		for (var i = 0; i < this.Adults.options.length; i++)
		{
			var option = this.Adults.options[i];
			if(option.value == selected)
			{
				option.selected = true;
			}
		}
	},
	setChild : function(selected)
	{
		for (var i = 0; i < this.Children.options.length; i++)
		{
			var option = this.Children.options[i];
			if(option.value == selected)
			{
				option.selected = true;
			}
		}
	},
	setDestination : function(selected)
	{
		for (var i = 0; i < this.Destination.options.length; i++)
		{
			var option = this.Destination.options[i];
			if(option.value.toUpperCase() == selected.toUpperCase())
			{
				option.selected = true;
			}
		}
	},
	setStartDate : function(startDate)
	{
		this.StartDate.updateDate(startDate);
	},
	setEndDate : function(endDate)
	{
		this.EndDate.updateDate(endDate);
	},
	getDestination : function ()
	{
		return this.Destination.options[this.Destination.selectedIndex == -1 ? 0 : this.Destination.selectedIndex].value;
	}
});

Mondial.ErrorDisplayControl = Class.create(
{
	Container: null,
	Title: "Error",
	Items: {},
	Height: 31,
	ProcessingDisplay: null,

	///Prototype Init Function - Called when object created
	initialize: function(container, processingDisplay)
	{
		this.Container = $(container);
		this.ProcessingDisplay = $(processingDisplay);
	},
	AppendAndDisplay: function(messages)
	{
		var errorTemplate1 = new Template('&#8226; #{message1}');
		var errorTemplate2 = new Template('1. #{message1}<br/>2. #{message2}');
		var errorTemplate3 = new Template('1. #{message1}<br/>2. #{message2}<br/>3. #{message3}');
		
		if (typeof (messages) === 'string')
		{
			this.Container.update(errorTemplate1.evaluate({ message1: messages, title: this.Title }));
		}
		else if (messages.length == 1)
		{
			this.Container.update(errorTemplate1.evaluate({ message1: messages[0], title: this.Title }));
		}
		else if (messages.length == 2)
		{
			this.Container.update(errorTemplate2.evaluate({ message1: messages[0], message2: messages[1], title: this.Title }));
		}
		else
		{
			this.Container.update(errorTemplate3.evaluate({ message1: messages[0], message2: messages[1], message3: messages[2], title: this.Title }));
		}
		Effect.Shake(this.Container.id);
		if (messages.length > 2)
		{
			this.Container.setStyle({ height: this.Height + 10 });
		}
		else
		{
			this.Container.setStyle({ height: this.Height });
		}
		this.Display();
	},
	AppendAndDisplayWarning: function(messages)
	{
		var errorTemplate1 = new Template('&#8226; #{message1}');
		var errorTemplate2 = new Template('1. #{message1}<br/>2. #{message2}');
		var errorTemplate3 = new Template('1. #{message1}<br/>2. #{message2}<br/>3. #{message3}');

		if (typeof (messages) === 'string')
		{
			this.Container.update(errorTemplate1.evaluate({ message1: messages, title: "Please Note:" }));
		}
		else if (messages.length == 1)
		{
			this.Container.update(errorTemplate1.evaluate({ message1: messages[0], title: "Please Note:" }));
		}
		else if (messages.length == 2)
		{
			this.Container.update(errorTemplate2.evaluate({ message1: messages[0], message2: messages[1], title: "Please Note:" }));
		}
		else
		{
			this.Container.update(errorTemplate3.evaluate({ message1: messages[0], message2: messages[1], message3: messages[2], title: "Please Note:" }));
		}
		Effect.Shake(this.Container.id);
		if (messages.length > 2)
		{
			this.Container.setStyle({ height: this.Height + 10 });
		}
		else
		{
			this.Container.setStyle({ height: this.Height });
		}
		this.Display();
	},
	Display: function()
	{
		this.Container.show();
		this.ProcessingDisplay.hide();
	},
	Hide: function()
	{
		this.Container.hide();
		this.ProcessingDisplay.show();
	}
});

Mondial.Ajax.Request = Class.create(Ajax.Request,
{
	_request : null,
	_respondToReadyState : null,
	running : false,
	autoCancel : true,
	
	///Prototype Init Function - Called when object created
	initialize : function($super, options)
	{
		this._request = this.request;
		this._respondToReadyState = this.respondToReadyState;
		this.request = Prototype.emptyFunction;
		$super(options);
		
		this.respondToReadyState = (function(readyState)
		{
			this.running = false;
			this._respondToReadyState(readyState);
		});
	},
	send : function (url)
	{
		if(this.autoCancel) this.cancel();
		this.running = true;
		this._request(url);		
	},
	cancel: function()
	{
		if(this.running)
		{
			this.running = false;
			this.transport.onreadystatechange = Prototype.emptyFunction;
			this.transport.abort();
		}
	}
});

Mondial.BaseService = Class.create(
{
	Request : null,
	RequestTimeout : 20, //Timeout in seconds
	aborted : false,
	Url : "",
	requestTimer : null,
	running : false,
	onComplete : null,
	onError : null,
	onStart : null,
	onNotFound : null,
	onTimeout : null,
	
	///Prototype Init Function - Called when object created
	initialize : function(url, onComplete, onError, onNotFound, onStart, onTimeout)
	{
		this.URL = url;
		this.onComplete = onComplete;
		this.onError = onError;
		this.onStart = onStart;
		this.onNotFound = onNotFound;
		this.onTimeout = onTimeout;
	},
	internalSubmit : function(url, method)
	{
		//If we have an existing request, abort it
		this.abortRequest();
		
		this.aborted = false;
		
		this.clearTimeout();
		
		//Make a call to the start function
		if(this.onStart) this.onStart();
		
		var modTime = "&MT=" + Math.random();
		
		this.setAbortRequestTimeout();
									
		this.Request = new Ajax.Request(url + modTime,
		{
			method      : method,
			onSuccess   : this.onSuccess.bind(this),
			on404       : this.onNotFound.bind(this),
			onFailure   : this.onError.bind(this)
		});
	},
	onException : function(e)
	{
		
	},
	abortRequest : function()
	{
		if(this.Request != null && this.Request.getStatus() != 200)
		{
		  this.aborted = true;
		  this.Request.transport.onreadystatechange = Prototype.emptyFunction;
			this.Request.transport.abort();
		}
	},
	clearTimeout : function()
	{
		if(this.requestTimer)
		{
			window.clearTimeout(this.requestTimer);
		}
	},
	onSuccess : function(response)
	{
		this.clearTimeout();
		if(this.aborted)
		{
			var timeout = this.onTimeout.bind(this);
			timeout(response);
		}
		else if(this.Request.success())
		{
			var complete = this.onComplete.bind(this);
			complete(response);
		}
	},
	setAbortRequestTimeout : function()
	{
		this.requestTimer = window.setTimeout((function() {this.abortRequest()}).bind(this), this.RequestTimeout * 1000);
	}
});

Mondial.StandardQuoteService = Class.create(Mondial.BaseService,
{
	///Prototype Init Function - Called when object created
	initialize: function($super, url, onComplete, onError, onNotFound, onStart, onTimeout)
	{
    $super(url, onComplete, onError, onNotFound, onStart, onTimeout);
	},
	Submit : function(intAdults, intDependants, strDestination, strStartDate, strEndDate, masterPlans)
	{
		var planIDs = "";
		
		for(var i = 0; i < masterPlans.length; i++)
		{
			planIDs = planIDs + masterPlans[i].Id + ";";
		}
	
		var urlParams = "&A=" + intAdults + "&C=" + intDependants+ "&R=" + strDestination + "&SD=" + strStartDate + "&ED=" + strEndDate + "&P=" + planIDs;
		
		this.internalSubmit(this.URL + "?op=QUOTE" + urlParams, 'GET');
	}
});

Mondial.WorldcareException = Class.create(
{
	///Prototype Init Function - Called when object created
	initialize : function(message)
	{
		this.Message = message;
		this.name = "WorldcareException";
	},
	toString : function()
	{
		return this.name + ': "' + this.Message + '"';
	}
});

var DomUtils =
{
	removeChildElements : function(c)
	{
		while (c.hasChildNodes())
		{
			c.removeChild(c.firstChild);
		}
	},
	appendChild : function (parent, elm, id)
	{
		if(Prototype.Browser.IE)
		{
			//Workaround bug in IE
			var y = document.createElement('div');
			y.id = id;
			y.innerHTML = elm.outerHTML;
			parent.appendChild(y);
		}
		else
		{
			parent.appendChild(elm);
		}
	},
	appendChildren : function (parent, elements, id)
	{
		if(Prototype.Browser.IE)
		{
			//Workaround bug in IE
			var y = document.createElement('div');
			y.id = id;
			elements.each(function(elm)
			{
				y.innerHTML = y.innerHTML + elm.outerHTML;
			});
			parent.appendChild(y);
		}
		else
		{
			elements.each(function(elm)
			{
				parent.appendChild(elm);
			});
		}
	},
	createPNGFixedStyle : function(imgURL, style)
	{
		return Mondial.ApplyPNGFix ? style + "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + imgURL + "', sizingMethod='scale');background-image:none;" : style;
	}
};

var CookieUtil =
{
	//Functions from http://www.quirksmode.org/js/cookies.html
	createCookie : function(name,value,days)
	{
		if (days)
		{
			var date = new Date();
			date.setTime(date.getTime()+(days*24*60*60*1000));
			var expires = "; expires="+date.toGMTString();
		}
		else var expires = "";
		
		document.cookie = name + "=" + value + expires + "; path=/";
	},
	readCookie : function(name)
	{
		var nameEQ = name + "=";
		var ca = document.cookie.split(';');
		for(var i=0;i < ca.length;i++) {
			var c = ca[i];
			while (c.charAt(0)==' ') c = c.substring(1,c.length);
			if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
		}
		return null;
	},
	eraseCookie : function(name)
	{
		this.createCookie(name,"",-1);
	}
};

Mondial.CookieHandler = Class.create(
{
	initialize : function()
	{
		
	},
	load : function()
	{
		var content = CookieUtil.readCookie(Mondial.SAB_COOKIE_NAME);
		if(content != null)
		{
			var quoteCookie = new Mondial.QuoteCookie();
			var obj = unescape(content).evalJSON(true);
			quoteCookie.Update(obj);
			return quoteCookie;
		}
		return null;
	},
	save : function(quoteCookie)
	{
		var jsonQuote = escape(Object.toJSON(quoteCookie));
		CookieUtil.createCookie(Mondial.SAB_COOKIE_NAME, jsonQuote);
	}
});
