var ONE_SECOND = 1000;
var ONE_MINUTE = 60 * ONE_SECOND;
var ONE_HOUR = 60 * ONE_MINUTE;
var ONE_DAY = 24 * ONE_HOUR;
var ONE_WEEK = 7 * ONE_DAY;
var MONTHS = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
var WEEKDAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
var WEEKDAYS_THREE = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];

function isSameDate(date1, date2) {
	if (date1 == date2) {
		return true;
	} else {
		if (date1 && date2) {
			return date1.getMonth() == date2.getMonth() && date1.getFullYear() == date2.getFullYear() && date1.getDate() == date2.getDate()		
		}
	}
	return false;
}

// The getMonthLen code seed taken from the JS Bible Gold, 4th Edition.  Listing 49-01, errata version (DST fixed)
//  month is 0-11
function getMonthLen(theYear, theMonth) {
    var oneHour = 1000 * 60 * 60;
    var oneDay  = oneHour * 24;
    var thisMonth   = new Date(theYear, theMonth,     1);
    var nextMonth   = new Date(theYear, theMonth + 1, 1);

    return (Math.ceil((nextMonth.getTime() - thisMonth.getTime() - oneHour)/oneDay));
}

// When the month changes, change the number of days available in the day dropdown.
function updateDaysInMonth(day, month, year) {
    // Expedia supports only 330 days, not 365    
    var current_date = new Date();
    var NUM_OF_DAYS_CI_AVAILABILITY = 329;
    var current_date_ms = current_date.getTime();
    var available_end_ci_date_ms = current_date_ms + (NUM_OF_DAYS_CI_AVAILABILITY * ONE_DAY);
    var available_end_ci_date = new Date(available_end_ci_date_ms);
    var available_end_co_date_ms = available_end_ci_date_ms + ONE_DAY;
    var available_end_co_date = new Date(available_end_co_date_ms);
    
    //alert('availability limit: ci=' + available_end_ci_date.toString() + ", co=" + available_end_co_date.toString());
    // Note: available_end_date will be in the 11th month

    //forms hack for IE, property page has 2 forms now and requires a lot of tinkering
    var myForm = getMyForm();
	var d = myForm[day];
	var m = myForm[month];
	var y = myForm[year];
    
    var startDayInSelectedMonth = 1;

    var originalIndex = d.selectedIndex;
    
    var monthFull = m[m.selectedIndex].text;
    var year = y.value;
    var col = monthFull.length - 4;
    if (col > 0 && monthFull.charAt(col - 1) == ' ') {
        year = monthFull.substr(col);
    }    
    
    var daysInSelectedMonth = getMonthLen(year, m[m.selectedIndex].value - 1);
    
    if (month.substr(0,2) == "CO") {
        if (tomorrowsDate) {
            if (m.selectedIndex == 1) { // tomorrow's month
                startDayInSelectedMonth = tomorrowsDate.getDate();
            }
            else if (m.selectedIndex == 12) { // Only show up to 330 days (Expedia)
                daysInSelectedMonth = available_end_co_date.getDate();
            }
        }
    }
    else {
        if (todaysDate) {
            if (m.selectedIndex == 1) { // this month
                startDayInSelectedMonth = todaysDate.getDate();
            }
            else if (m.selectedIndex == 12) { // Only show up to 330 days (Expedia)
                daysInSelectedMonth = available_end_ci_date.getDate();
            }
        }
    }
    
    var selectedDayOfMonth = d[d.selectedIndex].value;
    var selectedNewIndex = -1;
    d.length = daysInSelectedMonth + 1 - (startDayInSelectedMonth - 1);
    
    // -1 means not selected in SearchForm.
    d.options[0] = new Option('', -1);
    
    // add the rest of the days for the month
    for (i = startDayInSelectedMonth; i <= daysInSelectedMonth; ++i) {
        d.options[i - (startDayInSelectedMonth - 1)] = new Option(i, i);
        if (i == selectedDayOfMonth) {
            selectedNewIndex = i - (startDayInSelectedMonth - 1);
        }
    }

    if (originalIndex > 0) {
	    // handle when the day selected is no longer available (ex, 31 july, user selcts feb.  Day should change to 28)
	    if (selectedNewIndex == -1) {
	        if (selectedDayOfMonth > daysInSelectedMonth) {
	            d.selectedIndex = d.length - 1;
	        }
	        else {
	            d.selectedIndex = (d.length == 1) ? 0 : 1;
	        }
	    } else {
	        d.selectedIndex = selectedNewIndex;
	    }
    }    
    y.value = year;
}

function determineIfCheckoutSelectedByUser() {
    //forms hack for IE, property page has 2 forms now and requires a lot of tinkering
    var f = getMyForm();
    if (f.CODay.value != -1 || f.COMonth.value != -1) {
        checkOutSelectedByUser = true;
    } else {
        checkOutSelectedByUser = false;
    }
}


function determineIfCheckinSelectedByUser() {
    //forms hack for IE, property page has 2 forms now and requires a lot of tinkering
    var f = getMyForm();
    if (f.CIDay.value != -1 || f.CIMonth.value != -1) {
        checkInSelectedByUser = true;
    } else {
        checkInSelectedByUser = false;
    }
}


function selectCheckInDateBasedOnCheckOutDate() {
    //forms hack for IE, property page has 2 forms now and requires a lot of tinkering
/*
    if (document.forms[0].name == "myform") {
        var f = document.forms[0];
    } else {
        var f = document.forms[1];
    }
    var newMonth;
    var newDay;
    var newYear;

    if (!checkInSelectedByUser && f.CODay.value != -1 && f.COMonth.value != -1) {
        var ciDate = new Date(f.COYear.value, f.COMonth.value-1, f.CODay.value, 0, 0, 0);
        with (ciDate) {
            setDate(getDate() - determineDefaultLengthOfStay());
            newDay = getDate();
            newMonth = getMonth() + 1;
            newYear = getFullYear();
        }
        
        f.CIYear.value = newYear;
        doSelectMonth(newMonth + "", newYear + "", f.CIMonth.options); 
        updateDaysInMonth('CIDay','CIMonth', 'CIYear');
        f.CIDay.value = newDay;
        if (f.CIDay.value != newDay) {
            if (newDay < f.CIDay.options[1].value) {
                f.CIDay.selectedIndex = 1;
            } else {
                var lastValue = f.CIDay.options[f.CIDay.options.length-1].value;
                if (newDay > lastValue) {
                    f.CIDay.value = lastValue;
                }
            }
        }
        showDayOfWeek('CIDay','CIMonth','CIYear','CIDowArea');
    }*/
}


function selectCheckInDateBasedOnCheckOutDateDynamic(diwArea) {
    //forms hack for IE, property page has 2 forms now and requires a lot of tinkering
    /*
    if (document.forms[0].name == "myform") {
        var f = document.forms[0];
    } else {
        var f = document.forms[1];
    }
    var newMonth;
    var newDay;
    var newYear;

    if (!checkInSelectedByUser && f.CODay.value != -1 && f.COMonth.value != -1) {
        var ciDate = new Date(f.COYear.value, f.COMonth.value-1, f.CODay.value, 0, 0, 0);
        with (ciDate) {
            setDate(getDate() - determineDefaultLengthOfStay());
            newDay = getDate();
            newMonth = getMonth() + 1;
            newYear = getFullYear();
        }
        
        f.CIYear.value = newYear;
        doSelectMonth(newMonth + "", newYear + "", f.CIMonth.options); 
        updateDaysInMonth('CIDay','CIMonth', 'CIYear');
        f.CIDay.value = newDay;
        if (f.CIDay.value != newDay) {
            if (newDay < f.CIDay.options[1].value) {
                f.CIDay.selectedIndex = 1;
            } else {
                var lastValue = f.CIDay.options[f.CIDay.options.length-1].value;
                if (newDay > lastValue) {
                    f.CIDay.value = lastValue;
                }
            }
        }
        showDayOfWeek('CIDay','CIMonth','CIYear',diwArea);
    }*/
}




function selectCheckOutDateBasedOnCheckInDate() {
    //forms hack for IE, property page has 2 forms now and requires a lot of tinkering
    var f = getMyForm();
    var newMonth;
    var newDay;
    var newYear;

    if (!checkOutSelectedByUser && f.CIDay.value != -1 && f.CIMonth.value != -1) {
        var coDate = new Date(f.CIYear.value, f.CIMonth.value-1, f.CIDay.value, 0, 0, 0);
        with (coDate) {
            setDate(getDate() + determineDefaultLengthOfStay());
            newDay = getDate();
            newMonth = getMonth() + 1;
            newYear = getFullYear();
        }
        
        f.COYear.value = newYear;
        doSelectMonth(newMonth + "", newYear + "", f.COMonth.options); 
        updateDaysInMonth('CODay','COMonth', 'COYear');
        f.CODay.value = newDay;
        if (f.CODay.value != newDay) {
            if (newDay < f.CODay.options[1].value) {
                f.CODay.selectedIndex = 1;
            } else {
                var lastValue = f.CODay.options[f.CODay.options.length-1].value;
                if (newDay > lastValue) {
                    f.CODay.value = lastValue;
                }
            }
        }
        showDayOfWeek('CODay','COMonth','COYear','CODowArea');
    }
}

function selectCheckOutDateBasedOnCheckInDateDynamic(dowArea) {
    //forms hack for IE, property page has 2 forms now and requires a lot of tinkering
    var f = getMyForm();
    var newMonth;
    var newDay;
    var newYear;

    if (!checkOutSelectedByUser && f.CIDay.value != -1 && f.CIMonth.value != -1) {
        var coDate = new Date(f.CIYear.value, f.CIMonth.value-1, f.CIDay.value, 0, 0, 0);
        with (coDate) {
            setDate(getDate() + determineDefaultLengthOfStay());
            newDay = getDate();
            newMonth = getMonth() + 1;
            newYear = getFullYear();
        }
        
        f.COYear.value = newYear;
        doSelectMonth(newMonth + "", newYear + "", f.COMonth.options); 
        updateDaysInMonth('CODay','COMonth', 'COYear');
        f.CODay.value = newDay;
        if (f.CODay.value != newDay) {
            if (newDay < f.CODay.options[1].value) {
                f.CODay.selectedIndex = 1;
            } else {
                var lastValue = f.CODay.options[f.CODay.options.length-1].value;
                if (newDay > lastValue) {
                    f.CODay.value = lastValue;
                }
            }
        }
        showDayOfWeek('CODay','COMonth','COYear',dowArea);
    }
}

function showDayOfWeek(day, month, year, dowArea) {
    //forms hack for IE, property page has 2 forms now and requires a lot of tinkering
    var f = getMyForm();
    var d = eval("f." + day + ".value" );
    var m = eval("f." + month + ".value - 1" );
    var y = eval("f." + year + ".value" );
    var div = document.getElementById(dowArea);
    var dow = determineDayOfWeek(d, m, y);
    if (dow > -1) {
        div.innerHTML = WEEKDAYS_THREE[dow];
    } else {
        div.innerHTML = "";
    }
}

function determineDayOfWeek(d, m, y) {
    var ys = "" + y;
    if(ys.length == 4) {
        var c = new Date(y, m, d);
        if ((c.getDate() == d) && (c.getMonth() == m) && (c.getFullYear() == y)) {
            return c.getDay();
        }
    }

    return -1;
}

function doSelectMonth(theMonth, theYear, opts) {
    for (var i=0; i< opts.length; i++) {
        if (opts[i].value != theMonth) {
            opts[i].selected = false;
        }
        else {
            var col = opts[i].text.length - new String(theYear).length;
            if (col < 0) {
                opts[i].selected = false;
            }
            else {
                opts[i].selected = opts[i].text.substr(col) == theYear;
            }
        }
    }
}

function selectDate(date, type) {
	var f = getMyForm();
	if (type == "ci") {
		f.CIMonth.value = date.getMonth() + 1;
		f.CIYear.value = date.getFullYear();
		//updateDaysInMonth('CIDay','CIMonth', 'CIYear');
		f.CIDay.value = date.getDate();
	} else {
		f.COMonth.value = date.getMonth() + 1;
		f.COYear.value = date.getFullYear();
		//updateDaysInMonth('CODay','COMonth', 'COYear');
		f.CODay.value = date.getDate();
	}
}

/*
Copyright (c) 2008, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 2.6.0
*/
(function(){var B=YAHOO.util;var A=function(D,C,E,F){if(!D){}this.init(D,C,E,F);};A.NAME="Anim";A.prototype={toString:function(){var C=this.getEl()||{};var D=C.id||C.tagName;return(this.constructor.NAME+": "+D);},patterns:{noNegatives:/width|height|opacity|padding/i,offsetAttribute:/^((width|height)|(top|left))$/,defaultUnit:/width|height|top$|bottom$|left$|right$/i,offsetUnit:/\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i},doMethod:function(C,E,D){return this.method(this.currentFrame,E,D-E,this.totalFrames);},setAttribute:function(C,E,D){if(this.patterns.noNegatives.test(C)){E=(E>0)?E:0;}B.Dom.setStyle(this.getEl(),C,E+D);},getAttribute:function(C){var E=this.getEl();var G=B.Dom.getStyle(E,C);if(G!=="auto"&&!this.patterns.offsetUnit.test(G)){return parseFloat(G);}var D=this.patterns.offsetAttribute.exec(C)||[];var H=!!(D[3]);var F=!!(D[2]);if(F||(B.Dom.getStyle(E,"position")=="absolute"&&H)){G=E["offset"+D[0].charAt(0).toUpperCase()+D[0].substr(1)];}else{G=0;}return G;},getDefaultUnit:function(C){if(this.patterns.defaultUnit.test(C)){return"px";}return"";},setRuntimeAttribute:function(D){var I;var E;var F=this.attributes;this.runtimeAttributes[D]={};var H=function(J){return(typeof J!=="undefined");};if(!H(F[D]["to"])&&!H(F[D]["by"])){return false;}I=(H(F[D]["from"]))?F[D]["from"]:this.getAttribute(D);if(H(F[D]["to"])){E=F[D]["to"];}else{if(H(F[D]["by"])){if(I.constructor==Array){E=[];for(var G=0,C=I.length;G<C;++G){E[G]=I[G]+F[D]["by"][G]*1;}}else{E=I+F[D]["by"]*1;}}}this.runtimeAttributes[D].start=I;this.runtimeAttributes[D].end=E;this.runtimeAttributes[D].unit=(H(F[D].unit))?F[D]["unit"]:this.getDefaultUnit(D);return true;},init:function(E,J,I,C){var D=false;var F=null;var H=0;E=B.Dom.get(E);this.attributes=J||{};this.duration=!YAHOO.lang.isUndefined(I)?I:1;this.method=C||B.Easing.easeNone;this.useSeconds=true;this.currentFrame=0;this.totalFrames=B.AnimMgr.fps;this.setEl=function(M){E=B.Dom.get(M);};this.getEl=function(){return E;};this.isAnimated=function(){return D;};this.getStartTime=function(){return F;};this.runtimeAttributes={};this.animate=function(){if(this.isAnimated()){return false;}this.currentFrame=0;this.totalFrames=(this.useSeconds)?Math.ceil(B.AnimMgr.fps*this.duration):this.duration;if(this.duration===0&&this.useSeconds){this.totalFrames=1;}B.AnimMgr.registerElement(this);return true;};this.stop=function(M){if(!this.isAnimated()){return false;}if(M){this.currentFrame=this.totalFrames;this._onTween.fire();}B.AnimMgr.stop(this);};var L=function(){this.onStart.fire();this.runtimeAttributes={};for(var M in this.attributes){this.setRuntimeAttribute(M);}D=true;H=0;F=new Date();};var K=function(){var O={duration:new Date()-this.getStartTime(),currentFrame:this.currentFrame};O.toString=function(){return("duration: "+O.duration+", currentFrame: "+O.currentFrame);};this.onTween.fire(O);var N=this.runtimeAttributes;for(var M in N){this.setAttribute(M,this.doMethod(M,N[M].start,N[M].end),N[M].unit);}H+=1;};var G=function(){var M=(new Date()-F)/1000;var N={duration:M,frames:H,fps:H/M};N.toString=function(){return("duration: "+N.duration+", frames: "+N.frames+", fps: "+N.fps);};D=false;H=0;this.onComplete.fire(N);};this._onStart=new B.CustomEvent("_start",this,true);this.onStart=new B.CustomEvent("start",this);this.onTween=new B.CustomEvent("tween",this);this._onTween=new B.CustomEvent("_tween",this,true);this.onComplete=new B.CustomEvent("complete",this);this._onComplete=new B.CustomEvent("_complete",this,true);this._onStart.subscribe(L);this._onTween.subscribe(K);this._onComplete.subscribe(G);}};B.Anim=A;})();YAHOO.util.AnimMgr=new function(){var C=null;var B=[];var A=0;this.fps=1000;this.delay=1;this.registerElement=function(F){B[B.length]=F;A+=1;F._onStart.fire();this.start();};this.unRegister=function(G,F){F=F||E(G);if(!G.isAnimated()||F==-1){return false;}G._onComplete.fire();B.splice(F,1);A-=1;if(A<=0){this.stop();}return true;};this.start=function(){if(C===null){C=setInterval(this.run,this.delay);}};this.stop=function(H){if(!H){clearInterval(C);for(var G=0,F=B.length;G<F;++G){this.unRegister(B[0],0);}B=[];C=null;A=0;}else{this.unRegister(H);}};this.run=function(){for(var H=0,F=B.length;H<F;++H){var G=B[H];if(!G||!G.isAnimated()){continue;}if(G.currentFrame<G.totalFrames||G.totalFrames===null){G.currentFrame+=1;if(G.useSeconds){D(G);}G._onTween.fire();}else{YAHOO.util.AnimMgr.stop(G,H);}}};var E=function(H){for(var G=0,F=B.length;G<F;++G){if(B[G]==H){return G;}}return -1;};var D=function(G){var J=G.totalFrames;var I=G.currentFrame;var H=(G.currentFrame*G.duration*1000/G.totalFrames);var F=(new Date()-G.getStartTime());var K=0;if(F<G.duration*1000){K=Math.round((F/H-1)*G.currentFrame);}else{K=J-(I+1);}if(K>0&&isFinite(K)){if(G.currentFrame+K>=J){K=J-(I+1);}G.currentFrame+=K;}};};YAHOO.util.Bezier=new function(){this.getPosition=function(E,D){var F=E.length;var C=[];for(var B=0;B<F;++B){C[B]=[E[B][0],E[B][1]];}for(var A=1;A<F;++A){for(B=0;B<F-A;++B){C[B][0]=(1-D)*C[B][0]+D*C[parseInt(B+1,10)][0];C[B][1]=(1-D)*C[B][1]+D*C[parseInt(B+1,10)][1];}}return[C[0][0],C[0][1]];};};(function(){var A=function(F,E,G,H){A.superclass.constructor.call(this,F,E,G,H);};A.NAME="ColorAnim";A.DEFAULT_BGCOLOR="#fff";var C=YAHOO.util;YAHOO.extend(A,C.Anim);var D=A.superclass;var B=A.prototype;B.patterns.color=/color$/i;B.patterns.rgb=/^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;B.patterns.hex=/^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;B.patterns.hex3=/^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;B.patterns.transparent=/^transparent|rgba\(0, 0, 0, 0\)$/;B.parseColor=function(E){if(E.length==3){return E;}var F=this.patterns.hex.exec(E);if(F&&F.length==4){return[parseInt(F[1],16),parseInt(F[2],16),parseInt(F[3],16)];}F=this.patterns.rgb.exec(E);if(F&&F.length==4){return[parseInt(F[1],10),parseInt(F[2],10),parseInt(F[3],10)];}F=this.patterns.hex3.exec(E);if(F&&F.length==4){return[parseInt(F[1]+F[1],16),parseInt(F[2]+F[2],16),parseInt(F[3]+F[3],16)];}return null;};B.getAttribute=function(E){var G=this.getEl();
if(this.patterns.color.test(E)){var I=YAHOO.util.Dom.getStyle(G,E);var H=this;if(this.patterns.transparent.test(I)){var F=YAHOO.util.Dom.getAncestorBy(G,function(J){return !H.patterns.transparent.test(I);});if(F){I=C.Dom.getStyle(F,E);}else{I=A.DEFAULT_BGCOLOR;}}}else{I=D.getAttribute.call(this,E);}return I;};B.doMethod=function(F,J,G){var I;if(this.patterns.color.test(F)){I=[];for(var H=0,E=J.length;H<E;++H){I[H]=D.doMethod.call(this,F,J[H],G[H]);}I="rgb("+Math.floor(I[0])+","+Math.floor(I[1])+","+Math.floor(I[2])+")";}else{I=D.doMethod.call(this,F,J,G);}return I;};B.setRuntimeAttribute=function(F){D.setRuntimeAttribute.call(this,F);if(this.patterns.color.test(F)){var H=this.attributes;var J=this.parseColor(this.runtimeAttributes[F].start);var G=this.parseColor(this.runtimeAttributes[F].end);if(typeof H[F]["to"]==="undefined"&&typeof H[F]["by"]!=="undefined"){G=this.parseColor(H[F].by);for(var I=0,E=J.length;I<E;++I){G[I]=J[I]+G[I];}}this.runtimeAttributes[F].start=J;this.runtimeAttributes[F].end=G;}};C.ColorAnim=A;})();
/*
TERMS OF USE - EASING EQUATIONS
Open source under the BSD License.
Copyright 2001 Robert Penner All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
YAHOO.util.Easing={easeNone:function(B,A,D,C){return D*B/C+A;},easeIn:function(B,A,D,C){return D*(B/=C)*B+A;},easeOut:function(B,A,D,C){return -D*(B/=C)*(B-2)+A;},easeBoth:function(B,A,D,C){if((B/=C/2)<1){return D/2*B*B+A;}return -D/2*((--B)*(B-2)-1)+A;},easeInStrong:function(B,A,D,C){return D*(B/=C)*B*B*B+A;},easeOutStrong:function(B,A,D,C){return -D*((B=B/C-1)*B*B*B-1)+A;},easeBothStrong:function(B,A,D,C){if((B/=C/2)<1){return D/2*B*B*B*B+A;}return -D/2*((B-=2)*B*B*B-2)+A;},elasticIn:function(C,A,G,F,B,E){if(C==0){return A;}if((C/=F)==1){return A+G;}if(!E){E=F*0.3;}if(!B||B<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}return -(B*Math.pow(2,10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E))+A;},elasticOut:function(C,A,G,F,B,E){if(C==0){return A;}if((C/=F)==1){return A+G;}if(!E){E=F*0.3;}if(!B||B<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}return B*Math.pow(2,-10*C)*Math.sin((C*F-D)*(2*Math.PI)/E)+G+A;},elasticBoth:function(C,A,G,F,B,E){if(C==0){return A;}if((C/=F/2)==2){return A+G;}if(!E){E=F*(0.3*1.5);}if(!B||B<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}if(C<1){return -0.5*(B*Math.pow(2,10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E))+A;}return B*Math.pow(2,-10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E)*0.5+G+A;},backIn:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}return E*(B/=D)*B*((C+1)*B-C)+A;},backOut:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}return E*((B=B/D-1)*B*((C+1)*B+C)+1)+A;},backBoth:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}if((B/=D/2)<1){return E/2*(B*B*(((C*=(1.525))+1)*B-C))+A;}return E/2*((B-=2)*B*(((C*=(1.525))+1)*B+C)+2)+A;},bounceIn:function(B,A,D,C){return D-YAHOO.util.Easing.bounceOut(C-B,0,D,C)+A;},bounceOut:function(B,A,D,C){if((B/=C)<(1/2.75)){return D*(7.5625*B*B)+A;}else{if(B<(2/2.75)){return D*(7.5625*(B-=(1.5/2.75))*B+0.75)+A;}else{if(B<(2.5/2.75)){return D*(7.5625*(B-=(2.25/2.75))*B+0.9375)+A;}}}return D*(7.5625*(B-=(2.625/2.75))*B+0.984375)+A;},bounceBoth:function(B,A,D,C){if(B<C/2){return YAHOO.util.Easing.bounceIn(B*2,0,D,C)*0.5+A;}return YAHOO.util.Easing.bounceOut(B*2-C,0,D,C)*0.5+D*0.5+A;}};(function(){var A=function(H,G,I,J){if(H){A.superclass.constructor.call(this,H,G,I,J);}};A.NAME="Motion";var E=YAHOO.util;YAHOO.extend(A,E.ColorAnim);var F=A.superclass;var C=A.prototype;C.patterns.points=/^points$/i;C.setAttribute=function(G,I,H){if(this.patterns.points.test(G)){H=H||"px";F.setAttribute.call(this,"left",I[0],H);F.setAttribute.call(this,"top",I[1],H);}else{F.setAttribute.call(this,G,I,H);}};C.getAttribute=function(G){if(this.patterns.points.test(G)){var H=[F.getAttribute.call(this,"left"),F.getAttribute.call(this,"top")];}else{H=F.getAttribute.call(this,G);}return H;};C.doMethod=function(G,K,H){var J=null;if(this.patterns.points.test(G)){var I=this.method(this.currentFrame,0,100,this.totalFrames)/100;J=E.Bezier.getPosition(this.runtimeAttributes[G],I);}else{J=F.doMethod.call(this,G,K,H);}return J;};C.setRuntimeAttribute=function(P){if(this.patterns.points.test(P)){var H=this.getEl();var J=this.attributes;var G;var L=J["points"]["control"]||[];var I;var M,O;if(L.length>0&&!(L[0] instanceof Array)){L=[L];}else{var K=[];for(M=0,O=L.length;M<O;++M){K[M]=L[M];}L=K;}if(E.Dom.getStyle(H,"position")=="static"){E.Dom.setStyle(H,"position","relative");}if(D(J["points"]["from"])){E.Dom.setXY(H,J["points"]["from"]);}else{E.Dom.setXY(H,E.Dom.getXY(H));
}G=this.getAttribute("points");if(D(J["points"]["to"])){I=B.call(this,J["points"]["to"],G);var N=E.Dom.getXY(this.getEl());for(M=0,O=L.length;M<O;++M){L[M]=B.call(this,L[M],G);}}else{if(D(J["points"]["by"])){I=[G[0]+J["points"]["by"][0],G[1]+J["points"]["by"][1]];for(M=0,O=L.length;M<O;++M){L[M]=[G[0]+L[M][0],G[1]+L[M][1]];}}}this.runtimeAttributes[P]=[G];if(L.length>0){this.runtimeAttributes[P]=this.runtimeAttributes[P].concat(L);}this.runtimeAttributes[P][this.runtimeAttributes[P].length]=I;}else{F.setRuntimeAttribute.call(this,P);}};var B=function(G,I){var H=E.Dom.getXY(this.getEl());G=[G[0]-H[0]+I[0],G[1]-H[1]+I[1]];return G;};var D=function(G){return(typeof G!=="undefined");};E.Motion=A;})();(function(){var D=function(F,E,G,H){if(F){D.superclass.constructor.call(this,F,E,G,H);}};D.NAME="Scroll";var B=YAHOO.util;YAHOO.extend(D,B.ColorAnim);var C=D.superclass;var A=D.prototype;A.doMethod=function(E,H,F){var G=null;if(E=="scroll"){G=[this.method(this.currentFrame,H[0],F[0]-H[0],this.totalFrames),this.method(this.currentFrame,H[1],F[1]-H[1],this.totalFrames)];}else{G=C.doMethod.call(this,E,H,F);}return G;};A.getAttribute=function(E){var G=null;var F=this.getEl();if(E=="scroll"){G=[F.scrollLeft,F.scrollTop];}else{G=C.getAttribute.call(this,E);}return G;};A.setAttribute=function(E,H,G){var F=this.getEl();if(E=="scroll"){F.scrollLeft=H[0];F.scrollTop=H[1];}else{C.setAttribute.call(this,E,H,G);}};B.Scroll=D;})();YAHOO.register("animation",YAHOO.util.Anim,{version:"2.6.0",build:"1321"});
/*
Copyright (c) 2008, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 2.6.0
*/
YAHOO.util.Connect={_msxml_progid:["Microsoft.XMLHTTP","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP"],_http_headers:{},_has_http_headers:false,_use_default_post_header:true,_default_post_header:"application/x-www-form-urlencoded; charset=UTF-8",_default_form_header:"application/x-www-form-urlencoded",_use_default_xhr_header:true,_default_xhr_header:"XMLHttpRequest",_has_default_headers:true,_default_headers:{},_isFormSubmit:false,_isFileUpload:false,_formNode:null,_sFormData:null,_poll:{},_timeOut:{},_polling_interval:50,_transaction_id:0,_submitElementValue:null,_hasSubmitListener:(function(){if(YAHOO.util.Event){YAHOO.util.Event.addListener(document,"click",function(B){var A=YAHOO.util.Event.getTarget(B);if(A.nodeName.toLowerCase()=="input"&&(A.type&&A.type.toLowerCase()=="submit")){YAHOO.util.Connect._submitElementValue=encodeURIComponent(A.name)+"="+encodeURIComponent(A.value);}});return true;}return false;})(),startEvent:new YAHOO.util.CustomEvent("start"),completeEvent:new YAHOO.util.CustomEvent("complete"),successEvent:new YAHOO.util.CustomEvent("success"),failureEvent:new YAHOO.util.CustomEvent("failure"),uploadEvent:new YAHOO.util.CustomEvent("upload"),abortEvent:new YAHOO.util.CustomEvent("abort"),_customEvents:{onStart:["startEvent","start"],onComplete:["completeEvent","complete"],onSuccess:["successEvent","success"],onFailure:["failureEvent","failure"],onUpload:["uploadEvent","upload"],onAbort:["abortEvent","abort"]},setProgId:function(A){this._msxml_progid.unshift(A);},setDefaultPostHeader:function(A){if(typeof A=="string"){this._default_post_header=A;}else{if(typeof A=="boolean"){this._use_default_post_header=A;}}},setDefaultXhrHeader:function(A){if(typeof A=="string"){this._default_xhr_header=A;}else{this._use_default_xhr_header=A;}},setPollingInterval:function(A){if(typeof A=="number"&&isFinite(A)){this._polling_interval=A;}},createXhrObject:function(F){var E,A;try{A=new XMLHttpRequest();E={conn:A,tId:F};}catch(D){for(var B=0;B<this._msxml_progid.length;++B){try{A=new ActiveXObject(this._msxml_progid[B]);E={conn:A,tId:F};break;}catch(C){}}}finally{return E;}},getConnectionObject:function(A){var C;var D=this._transaction_id;try{if(!A){C=this.createXhrObject(D);}else{C={};C.tId=D;C.isUpload=true;}if(C){this._transaction_id++;}}catch(B){}finally{return C;}},asyncRequest:function(F,C,E,A){var D=(this._isFileUpload)?this.getConnectionObject(true):this.getConnectionObject();var B=(E&&E.argument)?E.argument:null;if(!D){return null;}else{if(E&&E.customevents){this.initCustomEvents(D,E);}if(this._isFormSubmit){if(this._isFileUpload){this.uploadFile(D,E,C,A);return D;}if(F.toUpperCase()=="GET"){if(this._sFormData.length!==0){C+=((C.indexOf("?")==-1)?"?":"&")+this._sFormData;}}else{if(F.toUpperCase()=="POST"){A=A?this._sFormData+"&"+A:this._sFormData;}}}if(F.toUpperCase()=="GET"&&(E&&E.cache===false)){C+=((C.indexOf("?")==-1)?"?":"&")+"rnd="+new Date().valueOf().toString();}D.conn.open(F,C,true);if(this._use_default_xhr_header){if(!this._default_headers["X-Requested-With"]){this.initHeader("X-Requested-With",this._default_xhr_header,true);}}if((F.toUpperCase()==="POST"&&this._use_default_post_header)&&this._isFormSubmit===false){this.initHeader("Content-Type",this._default_post_header);}if(this._has_default_headers||this._has_http_headers){this.setHeader(D);}this.handleReadyState(D,E);D.conn.send(A||"");if(this._isFormSubmit===true){this.resetFormState();}this.startEvent.fire(D,B);if(D.startEvent){D.startEvent.fire(D,B);}return D;}},initCustomEvents:function(A,C){var B;for(B in C.customevents){if(this._customEvents[B][0]){A[this._customEvents[B][0]]=new YAHOO.util.CustomEvent(this._customEvents[B][1],(C.scope)?C.scope:null);A[this._customEvents[B][0]].subscribe(C.customevents[B]);}}},handleReadyState:function(C,D){var B=this;var A=(D&&D.argument)?D.argument:null;if(D&&D.timeout){this._timeOut[C.tId]=window.setTimeout(function(){B.abort(C,D,true);},D.timeout);}this._poll[C.tId]=window.setInterval(function(){if(C.conn&&C.conn.readyState===4){window.clearInterval(B._poll[C.tId]);delete B._poll[C.tId];if(D&&D.timeout){window.clearTimeout(B._timeOut[C.tId]);delete B._timeOut[C.tId];}B.completeEvent.fire(C,A);if(C.completeEvent){C.completeEvent.fire(C,A);}B.handleTransactionResponse(C,D);}},this._polling_interval);},handleTransactionResponse:function(F,G,A){var D,C;var B=(G&&G.argument)?G.argument:null;try{if(F.conn.status!==undefined&&F.conn.status!==0){D=F.conn.status;}else{D=13030;}}catch(E){D=13030;}if(D>=200&&D<300||D===1223){C=this.createResponseObject(F,B);if(G&&G.success){if(!G.scope){G.success(C);}else{G.success.apply(G.scope,[C]);}}this.successEvent.fire(C);if(F.successEvent){F.successEvent.fire(C);}}else{switch(D){case 12002:case 12029:case 12030:case 12031:case 12152:case 13030:C=this.createExceptionObject(F.tId,B,(A?A:false));if(G&&G.failure){if(!G.scope){G.failure(C);}else{G.failure.apply(G.scope,[C]);}}break;default:C=this.createResponseObject(F,B);if(G&&G.failure){if(!G.scope){G.failure(C);}else{G.failure.apply(G.scope,[C]);}}}this.failureEvent.fire(C);if(F.failureEvent){F.failureEvent.fire(C);}}this.releaseObject(F);C=null;},createResponseObject:function(A,G){var D={};var I={};try{var C=A.conn.getAllResponseHeaders();var F=C.split("\n");for(var E=0;E<F.length;E++){var B=F[E].indexOf(":");if(B!=-1){I[F[E].substring(0,B)]=F[E].substring(B+2);}}}catch(H){}D.tId=A.tId;D.status=(A.conn.status==1223)?204:A.conn.status;D.statusText=(A.conn.status==1223)?"No Content":A.conn.statusText;D.getResponseHeader=I;D.getAllResponseHeaders=C;D.responseText=A.conn.responseText;D.responseXML=A.conn.responseXML;if(G){D.argument=G;}return D;},createExceptionObject:function(H,D,A){var F=0;var G="communication failure";var C=-1;var B="transaction aborted";var E={};E.tId=H;if(A){E.status=C;E.statusText=B;}else{E.status=F;E.statusText=G;}if(D){E.argument=D;}return E;},initHeader:function(A,D,C){var B=(C)?this._default_headers:this._http_headers;B[A]=D;if(C){this._has_default_headers=true;}else{this._has_http_headers=true;
}},setHeader:function(A){var B;if(this._has_default_headers){for(B in this._default_headers){if(YAHOO.lang.hasOwnProperty(this._default_headers,B)){A.conn.setRequestHeader(B,this._default_headers[B]);}}}if(this._has_http_headers){for(B in this._http_headers){if(YAHOO.lang.hasOwnProperty(this._http_headers,B)){A.conn.setRequestHeader(B,this._http_headers[B]);}}delete this._http_headers;this._http_headers={};this._has_http_headers=false;}},resetDefaultHeaders:function(){delete this._default_headers;this._default_headers={};this._has_default_headers=false;},setForm:function(M,H,C){var L,B,K,I,P,J=false,F=[],O=0,E,G,D,N,A;this.resetFormState();if(typeof M=="string"){L=(document.getElementById(M)||document.forms[M]);}else{if(typeof M=="object"){L=M;}else{return ;}}if(H){this.createFrame(C?C:null);this._isFormSubmit=true;this._isFileUpload=true;this._formNode=L;return ;}for(E=0,G=L.elements.length;E<G;++E){B=L.elements[E];P=B.disabled;K=B.name;if(!P&&K){K=encodeURIComponent(K)+"=";I=encodeURIComponent(B.value);switch(B.type){case"select-one":if(B.selectedIndex>-1){A=B.options[B.selectedIndex];F[O++]=K+encodeURIComponent((A.attributes.value&&A.attributes.value.specified)?A.value:A.text);}break;case"select-multiple":if(B.selectedIndex>-1){for(D=B.selectedIndex,N=B.options.length;D<N;++D){A=B.options[D];if(A.selected){F[O++]=K+encodeURIComponent((A.attributes.value&&A.attributes.value.specified)?A.value:A.text);}}}break;case"radio":case"checkbox":if(B.checked){F[O++]=K+I;}break;case"file":case undefined:case"reset":case"button":break;case"submit":if(J===false){if(this._hasSubmitListener&&this._submitElementValue){F[O++]=this._submitElementValue;}else{F[O++]=K+I;}J=true;}break;default:F[O++]=K+I;}}}this._isFormSubmit=true;this._sFormData=F.join("&");this.initHeader("Content-Type",this._default_form_header);return this._sFormData;},resetFormState:function(){this._isFormSubmit=false;this._isFileUpload=false;this._formNode=null;this._sFormData="";},createFrame:function(A){var B="yuiIO"+this._transaction_id;var C;if(YAHOO.env.ua.ie){C=document.createElement('<iframe id="'+B+'" name="'+B+'" />');if(typeof A=="boolean"){C.src="javascript:false";}}else{C=document.createElement("iframe");C.id=B;C.name=B;}C.style.position="absolute";C.style.top="-1000px";C.style.left="-1000px";document.body.appendChild(C);},appendPostData:function(A){var D=[],B=A.split("&"),C,E;for(C=0;C<B.length;C++){E=B[C].indexOf("=");if(E!=-1){D[C]=document.createElement("input");D[C].type="hidden";D[C].name=decodeURIComponent(B[C].substring(0,E));D[C].value=decodeURIComponent(B[C].substring(E+1));this._formNode.appendChild(D[C]);}}return D;},uploadFile:function(D,N,E,C){var I="yuiIO"+D.tId,J="multipart/form-data",L=document.getElementById(I),O=this,K=(N&&N.argument)?N.argument:null,M,H,B,G;var A={action:this._formNode.getAttribute("action"),method:this._formNode.getAttribute("method"),target:this._formNode.getAttribute("target")};this._formNode.setAttribute("action",E);this._formNode.setAttribute("method","POST");this._formNode.setAttribute("target",I);if(YAHOO.env.ua.ie){this._formNode.setAttribute("encoding",J);}else{this._formNode.setAttribute("enctype",J);}if(C){M=this.appendPostData(C);}this._formNode.submit();this.startEvent.fire(D,K);if(D.startEvent){D.startEvent.fire(D,K);}if(N&&N.timeout){this._timeOut[D.tId]=window.setTimeout(function(){O.abort(D,N,true);},N.timeout);}if(M&&M.length>0){for(H=0;H<M.length;H++){this._formNode.removeChild(M[H]);}}for(B in A){if(YAHOO.lang.hasOwnProperty(A,B)){if(A[B]){this._formNode.setAttribute(B,A[B]);}else{this._formNode.removeAttribute(B);}}}this.resetFormState();var F=function(){if(N&&N.timeout){window.clearTimeout(O._timeOut[D.tId]);delete O._timeOut[D.tId];}O.completeEvent.fire(D,K);if(D.completeEvent){D.completeEvent.fire(D,K);}G={tId:D.tId,argument:N.argument};try{G.responseText=L.contentWindow.document.body?L.contentWindow.document.body.innerHTML:L.contentWindow.document.documentElement.textContent;G.responseXML=L.contentWindow.document.XMLDocument?L.contentWindow.document.XMLDocument:L.contentWindow.document;}catch(P){}if(N&&N.upload){if(!N.scope){N.upload(G);}else{N.upload.apply(N.scope,[G]);}}O.uploadEvent.fire(G);if(D.uploadEvent){D.uploadEvent.fire(G);}YAHOO.util.Event.removeListener(L,"load",F);setTimeout(function(){document.body.removeChild(L);O.releaseObject(D);},100);};YAHOO.util.Event.addListener(L,"load",F);},abort:function(E,G,A){var D;var B=(G&&G.argument)?G.argument:null;if(E&&E.conn){if(this.isCallInProgress(E)){E.conn.abort();window.clearInterval(this._poll[E.tId]);delete this._poll[E.tId];if(A){window.clearTimeout(this._timeOut[E.tId]);delete this._timeOut[E.tId];}D=true;}}else{if(E&&E.isUpload===true){var C="yuiIO"+E.tId;var F=document.getElementById(C);if(F){YAHOO.util.Event.removeListener(F,"load");document.body.removeChild(F);if(A){window.clearTimeout(this._timeOut[E.tId]);delete this._timeOut[E.tId];}D=true;}}else{D=false;}}if(D===true){this.abortEvent.fire(E,B);if(E.abortEvent){E.abortEvent.fire(E,B);}this.handleTransactionResponse(E,G,true);}return D;},isCallInProgress:function(B){if(B&&B.conn){return B.conn.readyState!==4&&B.conn.readyState!==0;}else{if(B&&B.isUpload===true){var A="yuiIO"+B.tId;return document.getElementById(A)?true:false;}else{return false;}}},releaseObject:function(A){if(A&&A.conn){A.conn=null;A=null;}}};YAHOO.register("connection",YAHOO.util.Connect,{version:"2.6.0",build:"1321"});
if (typeof(Hotels) == "undefined") {
	Hotels = new Object();
}

if (typeof($) == "undefined" || typeof($) != 'function') {
	//$ = YAHOO.util.Dom.get;
	$ = function (id) { return document.getElementById(id); }
}

YAHOO.util.AnimMgr.fps = 10;

Hotels.RoomRateCalendarManager = {

	calendars: [],
	serverUri: '',

	setDateStayDates : function (ciDay, ciMonth, ciYear, coDay, coMonth, coYear) {
		if (ciMonth != -1 && coMonth != -1) {
			this.ciDate = new Date(ciYear, ciMonth - 1, ciDay);
			this.coDate = new Date(coYear, coMonth - 1, coDay);
		} else {
			this.ciDate = null;
			this.coDate = null;
		}
		this.oldCiDate = new Date(this.ciDate);	
		this.oldCoDate = new Date(this.coDate);
	},
	
	register : function (cal) {
		this.calendars.push(cal);
	},

	nextMonth : function() {
		for (var i = 0; i < this.calendars.length; i++) {
			this.calendars[i].nextMonth();
		}
	},
	
	prevMonth : function() {
		for (var i = 0; i < this.calendars.length; i++) {
			this.calendars[i].prevMonth();
		}
	},
	
	showCalendar: function(cal) {
		var cCal;
		for (var i = 0; i < this.calendars.length; i++) {
			cCal = this.calendars[i];
			// Don't animate opening same calendar.
			if (cCal.roomType == cal.roomType && cCal.ratePlan == cal.ratePlan) {
				cCal.showCalendar(cal != cCal);
			}
		}		
	},

	hideCalendar: function(cal) {
		var cCal;
		for (var i = 0; i < this.calendars.length; i++) {
			cCal = this.calendars[i];
			// Don't animate opening same calendar.
			if (cCal.roomType == cal.roomType && cCal.ratePlan == cal.ratePlan) {
				this.calendars[i].hideCalendar(cal != this.calendars[i]);
			}
		}		
	},

	updateStayDates: function(ciDate, coDate) {
		if (!isSameDate(this.ciDate, ciDate) || !isSameDate(this.coDate, coDate)) {
			this.ciDate = ciDate;	
			this.coDate = coDate;
			for (var i = 0; i < this.calendars.length; i++) {
				this.calendars[i].selectDates(ciDate, coDate);
			}
			this.updateLabels();
		}
	},
	
	updateLabels: function() {
		var noChange = isSameDate(this.coDate,this.oldCoDate) && isSameDate(this.ciDate,this.oldCiDate);
		if (noChange != this.changeState) {
			// Need some way to optimize this section.
			var dateBoxes = YAHOO.util.Dom.getElementsByClassName("dates", "div");
			for (var i = 0; i < dateBoxes.length; i++) {
				var p = dateBoxes[i].firstChild;
				if (noChange) {
					YAHOO.util.Dom.removeClass(dateBoxes[i], "change");
					YAHOO.util.Dom.removeClass(p, "change");
				} else {
					YAHOO.util.Dom.addClass(dateBoxes[i], "change");
					YAHOO.util.Dom.addClass(p, "change");				
				}
			}
			var buttons = YAHOO.util.Dom.getElementsByClassName("rateCalButtons", "span");
			for (var i = 0; i < buttons.length; i++) {
				var img = YAHOO.util.Dom.getElementsBy(function(){return true;}, "img", buttons[i]);
				if (noChange) {
					this.deActivateSubmit(img[1]);
					this.deActivateReset(img[0]);
				} else {
					this.activateSubmit(img[1]);
					this.activateReset(img[0]);
				}
			}
			this.changeState = noChange;
		}
	},
	
	refreshCalendars: function() {
		setTimeout(Hotels.RoomRateCalendarManager.refreshCalendars, 1000);
		for (var i = 0; i < Hotels.RoomRateCalendarManager.calendars.length; i++) {
			Hotels.RoomRateCalendarManager.calendars[i].refreshCalendar();
		}
	},
	
	resetDates: function(ev) {
		var target = YAHOO.util.Event.getTarget(ev);
		if (target.active) {
			this.ciDate = this.oldCiDate;
			this.coDate = this.oldCoDate;
			for (var i = 0; i < this.calendars.length; i++) {
				this.calendars[i].resetDates();
			}
			this.updateLabels();
		}
		return false;
	},
	
	checkRates: function(ev) {
		var target = YAHOO.util.Event.getTarget(ev);
		if (target.active) {
			setCookie("hcomRateCalPos", target.ratePlan+":"+target.roomType);
			// Populate and submit form.
			var f = document.forms[0];
			if (f.name != 'myform') {
				f = document.forms[1];
			}
			f.CIMonth.value = this.ciDate.getMonth() + 1;
			f.CIYear.value = this.ciDate.getFullYear();
			//updateDaysInMonth('CIDay','CIMonth', 'CIYear');
			f.CIDay.value = this.ciDate.getDate();
			f.COMonth.value = this.coDate.getMonth() + 1;
			f.COYear.value = this.coDate.getFullYear();
			//updateDaysInMonth('CODay','COMonth', 'COYear');
			f.CODay.value = this.coDate.getDate();
			
			try {
				Hotels.ClickTrack.click('CheckRatesRoomRateCalendar');
			} catch (errMsg) {
				this.statusMsg(errMsg);
			}
			
			f.submit();
			return true;
		}
		return false;
	},

	activateSubmit: function (el) {
		el.src = '/images/rateCalendar/btn_apply.gif';
		el.active = true;
		el.style.cursor = "pointer";
	},

	activateReset: function(el) {
		el.src = '/images/rateCalendar/btn_reset.gif';
		el.active = true;
		el.style.cursor = "pointer";
	},

	deActivateSubmit: function (el) {
		el.src = '/images/rateCalendar/btn_apply_grey.gif';
		el.active = false;
		el.style.cursor = "";
	},

	deActivateReset: function(el) {
		el.src = '/images/rateCalendar/btn_reset_grey.gif';
		el.active = false;
		el.style.cursor = "";
	},

	setupInteraction: function(sbmt, rst) {
		YAHOO.util.Event.addListener(sbmt, "click", 
			Hotels.RoomRateCalendarManager.checkRates,
			Hotels.RoomRateCalendarManager, true);
		sbmt.active = false;
		YAHOO.util.Event.addListener(rst, "click",
			Hotels.RoomRateCalendarManager.resetDates,
			Hotels.RoomRateCalendarManager, true);
		rst.active = false;
	},
	
	scrollBack: function() {
		var info = getCookie("hcomRateCalPos");
		if (info) {
			deleteCookie("hcomRateCalPos");
			var cCal;
			var rr = info.split(":");
			for (var i = 0; i < this.calendars.length; i++) {
				cCal = this.calendars[i];
				// Don't animate opening same calendar.
				if (cCal.roomType == rr[1] && cCal.ratePlan == rr[0]) {
					if (cCal.isVisible()) {
						var xy = YAHOO.util.Dom.getXY(cCal.container);
						window.scrollTo(xy[0],xy[1] - 50);
						return;
					}
				}
			}
		}
	},
	
	init: function() {
		var stat = Hotels.RoomRateCalendarManager;
		setTimeout(Hotels.RoomRateCalendarManager.refreshCalendars, 1000);
			
		// Init calendars first.
		for (var i = 0; i < stat.calendars.length; i++) {
			stat.calendars[i].init();
		}
			
		// delay a bit for the calendar to sort itself out.
		setTimeout(function() {stat.scrollBack()}, 500);
		this.inited = true;
	}
}

YAHOO.util.Event.addListener(window, "load", Hotels.RoomRateCalendarManager.init);

Hotels.RoomRateCalendar = function (config) {

	var _this = this;

	// Constants
	this.MAX_ATTEMPTS = 3;
	this.REQUEST_TIMEOUT = 15000;
	this.ALLOWED_RETRY = 3;
	this.INTERACTIVE = true;
	
	// Tracking vars
	this.created = false;
	this.navEnabled = true;
	this.selectingDate = false;
	this.expandedSixWeeks = false;
	
	this.thisMonth = (new Date()).getMonth() + 1;
	this.thisYear = (new Date()).getFullYear();
	this.monthIndex = 0;

	this.calendarUrl = "/RateCalendar.do";

	// Constructor stuff.
	this.calendarId = config.calendarId;
	this.propertyId = config.propertyId;
	this.roomType = config.roomTypeCode;
	this.ratePlan = config.ratePlanId;
	this.propertyType = config.propertyType;
	
	this.ciDate = Hotels.RoomRateCalendarManager.ciDate;
	this.coDate = Hotels.RoomRateCalendarManager.coDate;
	this.newCiDate = new Date(Hotels.RoomRateCalendarManager.ciDate);
	this.newCoDate = new Date(Hotels.RoomRateCalendarManager.coDate);

	if (config.avgRate) {
		this.avgRate = parseFloat(config.avgRate.replace(/\$/, ""));
	}

	// Get number of months to show based on 180 day window or checkout date.
	var f = new Date();
	
	// Safari bug fix.
	if (isSafari) {
		f.setDate(f.getDate() + 90);
		f.setDate(f.getDate() + 90); 
	} else {
		f.setDate(f.getDate() + 180);
	}
	
	var m = f.getMonth() + 1;
	if (this.newCoDate && (this.newCoDate > f || this.newCoDate.getMonth() == f.getMonth())) {
		if (this.newCiDate.getMonth() == this.newCoDate.getMonth()) {
			m = this.newCoDate.getMonth() + 2;
		} else {
			m = this.newCoDate.getMonth() + 1;
		}
	}
	if (this.thisMonth > m) m = m + 12;
	this.MAX_MONTHS = m - this.thisMonth + 1;
	
	this.calendarData = new Array(7);
	this.loadRetry = [];
	this.hasRequest = [];
	this.refreshLink = [];

	// These methods might have to change based on layout.
	// TODO: makes these render independant.
	this.DAY_CELL_SPACING = 9; // IE doesn't accept border-spacing, so we have to set cellspacing on the table itself.
	this.TOTAL_HEIGHT = 440; // Trial and error
	
	this.CALENDAR_WIDTH = 315; // Actual table width
	this.CALENDAR_SPACE = 10; // Table margins + 1 for implicit padding
	
	this.getCalendarOffset = function(i) {
		return (i * (this.CALENDAR_WIDTH  + this.CALENDAR_SPACE)) + ((i+1) * 2);
	}

	this.getCalendarLeft = function() {
		return YAHOO.util.Dom.getXY(this.calDiv.parentNode)[0];
	}

	this.getCurrentOffset = function(){
		return this.getCalendarLeft() - this.getCalendarOffset(this.monthIndex);
	}
	
	// Begin methods
	this.init = function() {
		var _this = this;

		// Dom Object refs
		this.container = $(this.calendarId + "_Container");
		this.calDiv = $(this.calendarId);
		this.dispDiv = $("calArea_" + this.calendarId);
		this.nextButton = $("next_" + this.calendarId);
		this.nextButton.enabled = true;
		this.prevButton = $("prev_" + this.calendarId);
		this.prevButton.enabled = true;
		this.errMsg = $("calErrMsg");
		this.loadingMsg = $("calLoading");
		this.showSpan = $("show_" + this.calendarId);
		this.hideSpan = $("hide_" + this.calendarId);
		this.showHide = $("showHide" + this.calendarId);
		this.showLink = $("showLink_" + this.calendarId);
		this.hideLink = $("hideLink_" + this.calendarId);
		this.ciLabel = $("checkin_"+this.calendarId);
		this.coLabel = $("checkout_"+this.calendarId);
		
		//create form so that DOJO can send AJAX request
		this.form = document.createElement("form");
		this.form.name = this.calendarId+"_Form1";
		this.form.id = this.calendarId+"_Form1";
		this.form.innerHTML =
			"<input type='hidden' name='dispatch' value='getRateCalendar'/>"+
			"<input type='hidden' name='roomTypeId' value='"+this.roomType+"'/>"+
			"<input type='hidden' name='ratePlanId' value='"+this.ratePlan+"'/>"+
			"<input type='hidden' name='mtnHotelId' value='"+this.propertyId+"'/>"+
			"<input type='hidden' name='supplierType' value='"+this.propertyType+"'/>"+
			"<input type='hidden' name='startMonth' value='0'/>" +
			"<input type='hidden' name='numberOfMonths' value='0'/>";
		document.body.appendChild(this.form);

		if (this.showHide) {
			YAHOO.util.Event.addListener(this.showHide, "click", this.onShowHideCalendar, this, true);
		}
		
		if (this.showLink) {
			YAHOO.util.Event.addListener(this.hideLink, "click", this.onHideCalendar, this, true);
		}
		
		if (this.hideLink) {
			YAHOO.util.Event.addListener(this.showLink, "click", this.onShowCalendar, this, true);
		}
		
		var mgr = Hotels.RoomRateCalendarManager;
		YAHOO.util.Event.addListener(this.nextButton, "click", mgr.nextMonth, mgr, true);
		this.nextButton.style.cursor = "pointer";
		YAHOO.util.Event.addListener(this.prevButton, "click", mgr.prevMonth, mgr, true);
		this.prevButton.style.cursor = "pointer";

		// Get month indexes (we use them alot)
		this.ciIndex = (this.ciDate)?this.getIndexFromMonth(this.ciDate.getMonth() + 1):0;
		this.coIndex = (this.coDate)?this.getIndexFromMonth(this.coDate.getMonth() + 1):0;
		this.monthIndex = this.ciIndex;
		if (this.INTERACTIVE) {
			var buttons = YAHOO.util.Dom.getElementsByClassName("rateCalButtons", "span", this.dispDiv);
			var img = YAHOO.util.Dom.getElementsBy(function(){return true;}, "img", buttons[0]);
			img[1].ratePlan = this.ratePlan;
			img[1].roomType = this.roomType;
			mgr.setupInteraction(img[1], img[0]);
		}

	
		if (this.isShowCalendar()) {
			this.showCalendar(true);
		}
		this.updateStayLabel();
		
	}

	this.createCalendars = function () {
		//create table containing each calendar
		var table = document.createElement("table");
		var tbody = document.createElement("tbody");
		var tr = document.createElement("tr");
		tr.style.verticalAlign = "top";
		tbody.appendChild(tr);
		table.appendChild(tbody);
		this.calDiv.appendChild(table);
		
		for (var i = 0; i < this.MAX_MONTHS; i++) {
			this.loadRetry[i] = this.ALLOWED_RETRY + 1;
			this.createCalendarGrid(i, tr, this.calDiv);
		}
	}

	this.createCalendarGrid = function(index, parentTr, containerDiv) {
		var month = this.getMonthFromIndex(index);
		var year = (month < this.thisMonth) ? (this.thisYear+1) : (this.thisYear) ;

		var containingTd = document.createElement("td");
		parentTr.appendChild(containingTd);

		var table = document.createElement("table");
		table.cellSpacing = this.DAY_CELL_SPACING - 1;
		var tbody = document.createElement("tbody");

		//month header
		var tr = document.createElement("tr");
		YAHOO.util.Dom.addClass(tr, "month");
		
		var td = document.createElement("th");
		YAHOO.util.Dom.addClass("month");
		td.scope = "col";
		td.colSpan = "7";
		
		var monthStr = MONTHS[month-1] + " " + year;
		td.innerHTML = monthStr;
		makeNonSelectable(td);
		tr.appendChild(td);
		tbody.appendChild(tr);
		
		//days header
		tr = document.createElement("tr");
		for (var i = 0; i < WEEKDAYS_THREE.length; i++) {
			this.addDayHeader(tr, i);
		}
		tbody.appendChild(tr);

		//weeks
		for (var w=1; w<=5; w++) {
			var tr = this.createCalendarWeek(index, w);
			tbody.appendChild(tr);
		}

		table.appendChild(tbody);
		containingTd.appendChild(table);

		//also add interstitial to div
		var loadingDiv = this.getLoadingDiv(index);
		containerDiv.appendChild(loadingDiv);
		loadingDiv.style.left = (this.getCalendarOffset(index) + 110) + "px";
		loadingDiv.style.top = "160px";
		loadingDiv.style.display = "none";
		
		// ErrorDiv
		var errorDiv = this.getErrorDiv(index);
		containerDiv.appendChild(errorDiv);
		errorDiv.style.display = "none";
		
		return table;
	}

	this.getCalWeekId = function(index, week) {
		var calWeekId = "cal" + index + "wk_" + this.calendarId + "_" + week;
		return calWeekId;
	}
	
	this.createCalendarWeek = function(index, week) {
		var tr = document.createElement("tr");
		tr.id = this.getCalWeekId(index, week);
		for (var d = 0; d < 7; d++) {
			td = document.createElement("td");
			td.innerHTML = "&nbsp;"
			tr.appendChild(td);
			YAHOO.util.Dom.addClass(td, "empty");
		}
		return tr;
	}
	
	this.getErrorDiv = function(index) {
		var _this = this;
		var errorDiv = document.createElement("div");
		errorDiv.innerHTML = this.errMsg.value;
		errorDiv = errorDiv.firstChild;
		errorDiv.id = this.getErrorDivId(index);
		errorDiv.style.left = (this.getCalendarOffset(index) + 10) + "px";
		var links = YAHOO.util.Dom.getElementsBy(function() { return true; }, "a", errorDiv);
		this.refreshLink[index] = links[0].parentNode;
		links[0].onclick = function() {
			if (_this.canReload(index)) {
				_this.retrieveCalendarData();
			} else {
				this.refreshLink[index].style.display = "none";
			}
			return false;
		}
		return errorDiv;
	}
	
	this.getLoadingDiv = function(index) {
		var loadingDiv = document.createElement("div");
		loadingDiv.innerHTML = this.loadingMsg.value;
		loadingDiv = loadingDiv.firstChild;
		loadingDiv.style.position = "absolute";
		loadingDiv.id = this.getInterstitialId(index);
		return loadingDiv;
	}
	
	this.getErrorDivId = function(index) {
		return "rateCalError_" + this.calendarId + "_" + index;
	}

	this.addDayHeader = function(tr, day) {
		var th = document.createElement("th");
		th.scope = "col";
		th.abbr = WEEKDAYS[day];
		th.title = WEEKDAYS_THREE[day];
		makeNonSelectable(th);
		th.appendChild(document.createTextNode(WEEKDAYS_THREE[day]));
		tr.appendChild(th);
	}

	this.initCalendar = function(skipErrors) {
		//move calendar into place
		this.togglePrev();
		this.toggleNext();
		
		var offsetX = this.getCurrentOffset();
		YAHOO.util.Dom.setX(this.calendarId, offsetX);

		this.retrieveCalendarData(skipErrors);
	}
	
	this.disableNav = function() {
		this.navEnabled = false;
		this.nextButton.style.cursor = "wait";
		this.prevButton.style.cursor = "wait";
	}
	
	this.enableNav = function() {
		this.navEnabled = true;
		this.nextButton.style.cursor = "pointer";
		this.prevButton.style.cursor = "pointer";
	}

	this.toggleNext = function() {
		if ((this.monthIndex + 1) == (this.MAX_MONTHS - 1)) {
			if (this.nextButton.enabled) {
				this.nextButton.src = "/images/rateCalendar/nextDis.gif";
				this.nextButton.enabled = false;
				this.nextButton.style.cursor = "default";
			}
		} else {
			if (! this.nextButton.enabled) {
				this.nextButton.src = "/images/rateCalendar/next.gif";
				this.nextButton.enabled = true;
				this.nextButton.style.cursor = "pointer";
			}
		}
	}
	
	this.togglePrev = function() {
		if (this.monthIndex == 0) {
			if (this.prevButton.enabled) {
				this.prevButton.src = "/images/rateCalendar/previousDis.gif";
				this.prevButton.enabled = false;
				this.prevButton.style.cursor = "default";
			}
		} else {
			if (!this.prevButton.enabled) {
				this.prevButton.src = "/images/rateCalendar/previous.gif";
				this.prevButton.enabled = true;
				this.prevButton.style.cursor = "pointer";
			}
		}
	}

	this.nextMonth = function() {
		var _this = this;
		if (this.monthIndex < this.MAX_MONTHS - 2) {
			if (this.navEnabled) {
				this.disableNav();
				this.monthIndex++;
				
				if (this.isVisible()) {
					this.toggleNext();
					this.togglePrev();
					
					this.retrieveCalendarData();
					var offsetX = -1 * this.getCalendarOffset(1);
					var a = new YAHOO.util.Motion(this.calendarId, {points:{by:[offsetX,0]}}, 0.75);
					a.onComplete.subscribe(
						function() {
							YAHOO.util.Dom.setX(_this.calendarId, _this.getCurrentOffset());
							_this.enableNav()
						}
					);
					a.animate();
				} else {
					this.enableNav();
				}
			}
		}
	}

	this.prevMonth = function() {
		var _this = this;
		if (this.monthIndex >  0) {
			if (this.navEnabled) {
				this.disableNav();
				this.monthIndex--;
				
				if (this.isVisible()) {
					this.toggleNext();
					this.togglePrev();
					
					this.retrieveCalendarData();
					var offsetX = this.getCalendarOffset(1);
					var a = new YAHOO.util.Motion(this.calendarId, {points:{by:[offsetX,0]}}, 0.75);
					a.onComplete.subscribe(function() {_this.enableNav();
						YAHOO.util.Dom.setX(_this.calendarId, _this.getCurrentOffset());});
					a.animate();
				} else {
					this.enableNav();
				}
			}
		}
	}

	this.canReload = function(index) {
		return !this.hasRequest[this.monthIndex] && this.loadRetry[index] > 0;
	}

	this.retrieveCalendarData = function(skipErrors) {
		var cal1 = this.calendarData[this.monthIndex];
		var cal2 = this.calendarData[this.monthIndex+1];
		
		if (cal1 && (skipErrors || !cal1.hasError) ) {
			if (cal2 && (skipErrors || !cal2.hasError)) {
				if (!this.hasRequest[this.monthIndex] && !this.hasRequest[this.monthIndex+1]) {
					this.renderCurrentCalendars();
				}
			} else {
				if (this.canReload(this.monthIndex+1)) {
					this.requestCalendar(this.monthIndex+1, 1);
				}
			}
		} else {
			if (cal2 && (skipErrors || !cal2.hasError)) {
				if (this.canReload(this.monthIndex)) {
					this.requestCalendar(this.monthIndex, 1);
				}
			} else {
				// Try for both, if that doesn't work, try each one (we may have two with error conditions).
				if (this.canReload(this.monthIndex) && this.canReload(this.monthIndex+1)) {
					this.requestCalendar(this.monthIndex, 2);
				}
				if (this.canReload(this.monthIndex)) {
					this.requestCalendar(this.monthIndex, 1);
				}
				if (this.canReload(this.monthIndex+1)) {
					this.requestCalendar(this.monthIndex+1, 1);
				}
			}
		}
	}

	this.requestCalendar = function(startMonthIndex, numMonths) {
		var startMonth = this.getMonthFromIndex(startMonthIndex);

		var _this = this;
		this.form.startMonth.value = startMonth;
		this.form.numberOfMonths.value = numMonths;
		
		YAHOO.util.Connect.setForm(this.form);
		var callback = {
			success: _this.handleResponse,
			failure: _this.handleError,
			scope: _this,
			timeout: _this.REQUEST_TIMEOUT,
			argument: [startMonthIndex, numMonths]
		}
		
		for (var i = startMonthIndex; i < startMonthIndex + numMonths; i++) {
			this.calendarLoading(i);
		}
		
		YAHOO.util.Connect.asyncRequest(
			'POST', _this.calendarUrl, callback, null);
	}

	this.getInterstitialId = function(index) {
		return "rateCalInterstitial_" + this.calendarId + "_" + index;
	}

	this.calendarLoading = function(index) {
		if (this.created) {
			$(this.getErrorDivId(index)).style.display = "none";
			var loadingDiv = $(this.getInterstitialId(index));
			loadingDiv.style.display = "block";
			this.hasRequest[index] = true;
			this.loadRetry[index]--;
		}
	}
	
	this.calendarLoaded = function(index) {
		if (this.created) {
			$(this.getInterstitialId(index)).style.display = "none";
		}
	}

	this.handleResponse = function(response) {
	
		var jsonResponse;
		try {
			var txt = response.responseText;
			var cmntIndex = txt.indexOf("<!--");
			if (cmntIndex > 0) {
				txt = txt.substring(0, cmntIndex);
			}
			jsonResponse = eval('(' + txt + ')');
		} catch (err) {
			this.handleError(response);
		}
		
		if (jsonResponse.hasError) {
			this.handleError(response);		
		}
		
		for (var i = 0; i < jsonResponse.calendar.length; i++) {
			var month = jsonResponse.calendar[i];
			var index = this.getIndexFromMonth(month.month);
			
			//hide interstiial
			this.calendarLoaded(index);
			this.hasRequest[index] = false;
			month.hasError = jsonResponse.hasError;
			this.calendarData[index] = month;
		}

		this.checkAverage();
		this.renderCurrentCalendars();

	}

	this.hideRates = false;
	this.doCheckAverage = true;
	this.checkAverage = function() {
		if (!this.hideRates) {
			if (this.calendarData[this.ciIndex] && this.calendarData[this.coIndex]
				&& !this.calendarData[this.ciIndex].hasError && !this.calendarData[this.coIndex].hasError) {
				this.doCheckAverage = false;
				var count = 0; var total = 0;
				for (var i = this.ciIndex; i <= this.coIndex; i++) {
					var data = this.calendarData[i];
					if (!data.hasError) {
						for (var j = 0; j < data.weeks.length; j++) {
							for (var k = 0; k < data.weeks[j].length; k++) {
								var day = data.weeks[j][k];
								if (this.getRateDate(day) >= this.ciDate && this.getRateDate(day) < this.coDate) {
									if (!day.isInvalidDay && day.roomRate) {
										count++;
										total += parseFloat(day.roomRate.replace(/\$/, ""));
									}
								}
							}
						}
					}
				}
				
				if (count > 0 && (this.avgRate > (total / count))) {
					this.hideRates = true;
				}
			}
		}
	}
	
	this.handleError = function(response) {
		var args = response.argument;
		for (var index = args[0]; index < args[0] + args[1]; index++) {
			var errDivId = this.getErrorDivId(index);
			if (!this.calendarData[index]) {
				this.calendarData[index] = new Object();
			}
			this.calendarData[index].hasError = true;
			this.hasRequest[index] = false;
			this.calendarLoaded(index);
		}

		this.renderCurrentCalendars();
	}
	
	this.renderCurrentCalendars = function() {
		if (this.calendarData[this.monthIndex] && this.calendarData[this.monthIndex+1]) {
			var rateLimits = this.getCurrentRateLimits();
			for (var i=0; i<2; i++) {
				var index = i + this.monthIndex;
				var errDivId = this.getErrorDivId(index);
				var cData = this.calendarData[index];
				if (cData.hasError) {
					// Show error msg
					$(errDivId).style.display = "block";
					if (this.loadRetry[index] < 1) {
						this.refreshLink[index].style.display = "none";
					}
				} else {
					$(errDivId).style.display = "none";
					var data = cData.weeks;
					var dummy = new Object();
					var numWeeks = Math.min(data.length, 6);
			
					for (var w = 0; w < numWeeks; w++) {
						
						var calWeek = $(this.getCalWeekId(index, w + 1));
						if (!calWeek) {
							// We have a 6th week, time to add another row.
							var prevCalWeek = $(this.getCalWeekId(index, w));
							var tr = this.createCalendarWeek(index, w + 1);
							prevCalWeek.parentNode.appendChild(tr);
							calWeek = $(this.getCalWeekId(index, w + 1));
							this.expandToSixWeeks(prevCalWeek);
						}
						
						for (var d = 0; d < 7; d++) {
							var dayCell = calWeek.childNodes[d];
							// Feed in a blank if there's an error, so we clear the calendar.
							var dayData = (cData.hasError) ? dummy : data[w][d];
							this.setDayCell(dayData, dayCell, rateLimits);
						}
					}
					if (this.INTERACTIVE && !cData.interactive) {
						this.setupInteraction(cData);
					}
				}
			}
			if (this.INTERACTIVE) {
				this.resetSelectIndicies();
			}
		}
	}
	
	this.expandToSixWeeks = function(week) {
		if (!this.expandedSixWeeks) {
			if (this.canBeVisible()) {
				var day = YAHOO.util.Dom.getRegion(week);
				var dayHeight = day.bottom - day.top;
				this.TOTAL_HEIGHT += dayHeight;
				
				var a1 = new YAHOO.util.Anim(this.calDiv);
				a1.attributes.height = { by: dayHeight };
				var a2 = new YAHOO.util.Anim(this.calDiv.parentNode);
				a2.attributes.height = { by: dayHeight };
				var a3 = new YAHOO.util.Anim(this.dispDiv);
				var _this = this;
				a3.attributes.height = { to: this.TOTAL_HEIGHT };
				a3.onComplete.subscribe(function() {
					_this.reflow()
				})

				a1.animate();
				a2.animate();
				a3.animate();

				this.expandedSixWeeks = true;
			}
		} 
	}

	// Price state cells
	this.lowCell = function(cell) {
		YAHOO.util.Dom.removeClass(cell, "avg");
		YAHOO.util.Dom.removeClass(cell, "high");
		YAHOO.util.Dom.addClass(cell, "low");
		cell.title = "Lower price";
	}
	
	this.highCell = function(cell) {
		YAHOO.util.Dom.removeClass(cell, "avg");
		YAHOO.util.Dom.removeClass(cell, "low");
		YAHOO.util.Dom.addClass(cell, "high");
		cell.title = "Higher price";		
	}

	this.avgCell = function(cell) {
		YAHOO.util.Dom.removeClass(cell, "high");
		YAHOO.util.Dom.removeClass(cell, "low");
		YAHOO.util.Dom.addClass(cell, "avg");		
		cell.title = "Average price";
	}
	
	// State State Cells
	this.selectCell = function(cell) {
		YAHOO.util.Dom.removeClass(cell, "checkout");
		YAHOO.util.Dom.replaceClass(cell, "origSelected", "selected");
	}
	
	this.origStayCell = function (cell) {
		YAHOO.util.Dom.removeClass(cell, "checkout");
		YAHOO.util.Dom.replaceClass(cell, "selected", "origSelected");		
	}
	
	this.coCell = function (cell) {
		YAHOO.util.Dom.addClass(cell, "checkout");
	}
	
	this.unSelectCell = function(cell) {
		YAHOO.util.Dom.removeClass(cell, "checkout");
		YAHOO.util.Dom.removeClass(cell, "selected");
		YAHOO.util.Dom.removeClass(cell, "origSelected");		
	}
	
	// Info cells never change, so no need to remove other styles.
	this.checkRatesCell = function(cell) {
		YAHOO.util.Dom.addClass(cell, "info");
	}

	this.setDayCell = function(dayObj, cell, rateLimits) {
		if (!rateLimits) {
			rateLimits = this.getCurrentRateLimits();
		}
		
		var cellHtml = "";
		if (dayObj.date && dayObj.date != "") {
			YAHOO.util.Dom.removeClass(cell, "empty");
			dayObj.checkout = false;
			if (this.isDateSelected(dayObj.date, dayObj.month)) {
				this.selectCell(cell);
			} else if (this.isCoDate(dayObj.date, dayObj.month)) {
				this.coCell(cell);
				dayObj.checkout = true;
			} else if (this.wasDateSelected(dayObj.date, dayObj.month)) {
				this.origStayCell(cell);
			} else {
				this.unSelectCell(cell);
			}

			if (dayObj.isInvalidDay) {
				cellHtml = dayObj.date;
			} else {
				if (dayObj.isCheckRates) {
					this.checkRatesCell(cell);
					cellHtml = dayObj.date + this.getRateSpan("Call");
				} else {
					var rate = this.getIntRate(dayObj.roomRate);
					if (rate <= rateLimits.minMedium) {
						this.lowCell(cell);
					} else if (rate <= rateLimits.maxMedium) {
						this.avgCell(cell);
					} else {
						this.highCell(cell);
					}
					
					cellHtml = dayObj.date;
					if (!this.hideRates && "USD" == dayObj.currency) {
						cellHtml += this.getRateSpan("$" + rate);
					}
				}
			}
			
			dayObj.cell = cell;
		} else {
			YAHOO.util.Dom.addClass(cell, "empty");
		}
		cell.innerHTML = cellHtml;
	}
	
	this.getRateSpan = function(rate) {
		return "<span class=\"rate\">" + rate + "</span>";
	}

	//figure out avg minanmax (color limits) for the 2 months currently shown
	this.getCurrentRateLimits = function() {
		var minRate = 99999;
		var maxRate = 0;
		var rateHashMap = new Object();

		for (var i=this.monthIndex; i <= this.monthIndex+1; i++ ) {
			if (!this.calendarData[i].hasError) {
				var data = this.calendarData[i].weeks;
				for (var w = 0; w < data.length; w++) {
					for (var d = 0; d < 7; d++) {
						if (data[w][d].roomRate != "") {
							if (data[w][d].roomRate && data[w][d].roomRate != "") {
								var rate = this.getIntRate(data[w][d].roomRate);
								if (rate < minRate) {
									minRate = rate;
								}
								if (rate > maxRate) {
									maxRate = rate;
								}
								rateHashMap[""+rate] = rate;
							}
						}
					}
				}
			}
		}

		var numberUniqueRates =0;
		for (property in rateHashMap) {
			numberUniqueRates++;
		}

		var limits = new Object();

		if (numberUniqueRates <= 1) { //only 1 rate: all medium
			limits.minMedium = 0;
			limits.maxMedium = 99999;
		}
		else if (numberUniqueRates == 2) { //2 rates: 1 low, 1 medium
			limits.minMedium = minRate;
			limits.maxMedium = 99999;
		}
		else if (numberUniqueRates == 3) { //3 rates: 1 rate in each category
			var middleRate = 0;
			for (property in rateHashMap) {
				var rate = rateHashMap[property];
				if ((rate != minRate) && (rate != maxRate)) {
					middleRate = rate;
				}
			}
			limits.minMedium = minRate;
			limits.maxMedium = middleRate;
		}
		else { //4+ rates: low=first25% of diff; high=last 25% of diff
			var spread =  ((maxRate -  minRate) * 0.25);
			limits.minMedium = minRate + spread;
			limits.maxMedium = maxRate - spread;
		}

		return limits;
	}

	this.getIntRate = function(rate) {
		if (rate && rate != "") {
			var posPeriod = rate.indexOf(".");
            var startPos = 0;
            if ("0123456789".indexOf(rate.charAt(0)) == -1) {
                startPos = 1;
            }
            var truncatedRate = rate.substring(startPos, posPeriod);
            truncatedRate = truncatedRate.replace(/\,/,"");
			return parseInt(truncatedRate);
		}

		return -1;
	}

	this.onShowCalendar = function() {
		Hotels.RoomRateCalendarManager.showCalendar(this);
		try {
			// Try to register Hotels.ClickTrack.click, but don't let the app break if it doesn't work.
			Hotels.ClickTrack.click('SeeRoomRateCalendar');
		} catch (errMsg) {
			this.statusMsg(errMsg);
		}
	}
	
	this.onHideCalendar = function() {
		Hotels.RoomRateCalendarManager.hideCalendar(this);
	}

	this.onShowHideCalendar = function() {
		if (YAHOO.util.Dom.hasClass("showHide" + this.calendarId, "hidden")) {
			this.onShowCalendar();
		} else {
			this.onHideCalendar();
		}
	}

	this.revealCalendar = function(noAnimate) {
	
		this.showSpan.style.display = "none";
		this.hideSpan.style.display = "block"
		YAHOO.util.Dom.replaceClass(this.showHide, "hidden", "visible");
		var v = this.dispDiv;
		if (noAnimate) {
			v.style.height = this.TOTAL_HEIGHT + "px";
			this.reflow()
		} else {
			var a1 = new YAHOO.util.Anim(v);
			a1.attributes.height = { to: this.TOTAL_HEIGHT };
			a1.duration = 0.5
			var _this = this;
			a1.onComplete.subscribe(function() {
				_this.reflow()
			})
			a1.animate();
		}
	}
	
	this.concealCalendar = function(noAnimate) {
		var _this = this;
		this.showSpan.style.display = "block";
		this.hideSpan.style.display = "none";
		var v = this.dispDiv;
		if (noAnimate) {
			YAHOO.util.Dom.replaceClass(this.showHide, "visible", "hidden");
			v.style.height = "0px";
			this.reflow()
		} else {
			var a1 = new YAHOO.util.Anim(v);
			a1.attributes.height = { to: 0 };
			a1.animate();
			a1.onComplete.subscribe(function() {
				YAHOO.util.Dom.replaceClass(_this.showHide, "visible", "hidden");
				_this.reflow()
			});
		}
	}
	
	this.reflow = function() {
		if (isIE) {
			if (!this.cpDivs) {
				this.cpDivs = YAHOO.util.Dom.getElementsByClassName("cancellationPolicy", "li", "roomRates");
			}
			if (this.cpDivs) {
				YAHOO.util.Dom.addClass(this.cpDivs, "tmp");
				YAHOO.util.Dom.removeClass(this.cpDivs, "tmp");
			}
			if (!this.calAreaDivs) { 
				this.calAreaDivs = YAHOO.util.Dom.getElementsByClassName("calArea");
			}
			if (this.calAreaDivs) {
				YAHOO.util.Dom.addClass(this.calAreaDivs, "unstick");
				YAHOO.util.Dom.removeClass(this.calAreaDivs, "unstick");
			}
		}
	}

	this.refreshed = false;
	this.refreshCalendar = function() {
		if (this.canBeVisible()) {
			if (this.delayedShow) {
				this.showCalendar(true);
				this.delayedShow = false;
			} else {
				if (this.created){
					if (!this.refreshed) {
						this.initCalendar(true);
						this.refreshed = true;
					}
				}
			}
		} else {
			this.refreshed = false;
		}
	}
	
	this.canBeVisible = function() {
		var xy = YAHOO.util.Dom.getXY(this.calDiv);
		return (typeof(xy) != 'undefined' && xy != false && xy[0] != 0);
	}

	this.isVisible = function() {
		// Hack, cause we know this shouldn't be a zero (for IE)
		return this.created && this.showing && this.canBeVisible();
	}
	
	this.isShowCalendar = function() {
		return getCookie(this.calendarId + "_open") == "true";
	}

	this.showCalendar = function (noAnimate) {
		this.requestCalendar(this.ciIndex, this.coIndex - this.ciIndex + 1);
		this.checkAverage();

		if (this.canBeVisible()) {
			if (!this.created) {
				this.createCalendars();
				this.created = true;
			}
			this.revealCalendar(noAnimate);			
			this.initCalendar();
		} else {
			this.delayedShow = true;
		}

		
		this.showing = true;
		setCookie(this.calendarId + "_open", "true");
		return false;
	}
	
	this.hideCalendar = function (noAnimate) {
		this.concealCalendar(noAnimate);
		this.delayedShow = false;
		deleteCookie(this.calendarId + "_open");
		this.showing = false;
		return false;
	}

	this.getIndexFromMonth = function(actualMonth) {
		var index = actualMonth - this.thisMonth;

		if (actualMonth < this.thisMonth) {
			index +=12;
		}

		return index;
	}

	this.getMonthFromIndex = function(monthIndex) {
		var month = monthIndex + this.thisMonth
		return (month <= 12) ? month:month % 12
	}

	this.getCompDate = function(day, month) {
		var year = (month >= this.thisMonth) ? this.thisYear : (this.thisYear + 1);
		return new Date(year, month - 1, day);
	}

	this.wasDateSelected = function(day, month) {
		var date = this.getCompDate(day, month);
		return ((date >= this.ciDate) && (date < this.coDate));
	}

	this.isCoDate = function(day, month) {
		var date = this.getCompDate(day, month);
		return isSameDate(date, this.newCoDate);
	}

	this.isDateSelected = function(day, month) {
		if (this.newCiDate && this.newCoDate) {
			var date = this.getCompDate(day, month);
			return ((date >= this.newCiDate) && (date < this.newCoDate));
		} else {
			return false;
		}
	}

	this.statusMsg = function(msg) {
		window.status = msg;
	}

	// Interactivity stuff.	
	this.selectingDate = false;
	
	this.setupInteraction = function(cData) {
		var weeks = cData.weeks;
		var numWeeks = Math.min(weeks.length, 6);
		for (var w = 0; w < numWeeks; w++) {
			for (var d = 0; d < 7; d++) {
				var dayObj = weeks[w][d];
				if (dayObj.date && dayObj.date != "" && !dayObj.isInvalidDay) {
					var cell = dayObj.cell;
					makeNonSelectable(cell);
					cell.onmousedown = null; // Clear the onmousedown one cause we want to use it.
					YAHOO.util.Event.addListener(cell, "mousedown", this.createOnMouseDown(dayObj), this, true);
					YAHOO.util.Event.addListener(cell, "mouseup", this.createOnMouseUp(dayObj), this, true);
					YAHOO.util.Event.addListener(cell, "mouseover", this.createOnMouseOver(dayObj), this, true);
					YAHOO.util.Event.addListener(cell, "mouseout", this.createOnMouseOut(dayObj), this, true);
				}
			}
		}
		cData.interactive = true;
	}
	
	this.createOnMouseDown = function (dayObj) {
		return function(evt) {
			if (!_this.selectingDate) {
				_this.startTarget = YAHOO.util.Event.getTarget(evt);
				_this.startSelect(dayObj);
			}
		}
	}
	
	this.createOnMouseOver = function(dayObj) {
		return function(evt) {
			if (dayObj.checkout) {
				YAHOO.util.Dom.removeClass(dayObj.cell, "checkout");
			}
			_this.duringSelect(dayObj);
		}
	}
	
	this.createOnMouseOut = function(dayObj) {
		return function(evt) {
			if (dayObj.checkout) {
				YAHOO.util.Dom.addClass(dayObj.cell,"checkout");
			}
		}
	}
	
	this.createOnMouseUp = function(dayObj) {
		return function(evt) {
			var endTarget = YAHOO.util.Event.getTarget(evt);
			if (endTarget != _this.startTarget) {
				_this.finishSelect(dayObj);
			}
		}
	}
	
	this.startSelect = function(dateObj) {
		this.clearSelected();
		this.selectStartDate = dateObj;
		this.selectCell(dateObj.cell);
		this.selectingDate = true;
		this.updateCiLabel(this.getRateDate(this.selectStartDate));
	}
	
	this.duringSelect = function(dateObj) {
		if (this.selectingDate) {
			this.clearSelected();
			var endIndex = this.selectRange(this.selectStartDate.selectedIndex, dateObj.selectedIndex);	
		}
	}

	this.finishSelect = function(dateObj) {
		var endIndex = this.selectRange(this.selectStartDate.selectedIndex, dateObj.selectedIndex);
		var endDateObj = this.dateBoxes[endIndex];
		this.newCiDate = this.getRateDate(this.selectStartDate); 
		this.newCoDate = this.getRateDate(endDateObj);
		if (this.newCiDate > this.newCoDate) {
			var tmp = this.newCiDate;
			this.newCiDate = this.newCoDate;
			this.newCoDate = tmp;
		}
		this.selectingDate = false;
		Hotels.RoomRateCalendarManager.updateStayDates(this.newCiDate, this.newCoDate);
	}

	this.clickDate = function(dateObj) {
		if (!this.selectingDate) {
			this.startSelect(dateObj);
		} else {
			this.finishSelect(dateObj);
		}
	}

	this.resetSelected = function() {
		if (this.isVisible()) {
			var rateLimits = this.getCurrentRateLimits();
			for (var i = 0; i < this.dateBoxes.length; i++) {
				var dayObj = this.dateBoxes[i]
				this.setDayCell(dayObj, dayObj.cell, rateLimits);
			}
		}		
	}
	
	this.clearSelected = function() {
		if (this.isVisible()) {
			var rateLimits = this.getCurrentRateLimits();
			for (var i = 0; i < this.dateBoxes.length; i++) {
				var dayObj = this.dateBoxes[i]
				if (this.wasDateSelected(dayObj.date, dayObj.month)) {
					this.origStayCell(dayObj.cell);
				} else {
					this.unSelectCell(dayObj.cell);
				}
			}
		}
	}
	
	this.resetSelectIndicies = function() {
		this.dateBoxes = [];
		
		if (this.selectingDate) {
			this.selectingDate = false;			
		}
		
		for (var i=this.monthIndex; i <= this.monthIndex+1; i++ ) {
			var data = this.calendarData[i].weeks;
			for (var w = 0; w < data.length; w++) {
				for (var d = 0; d < 7; d++) {
					if (data[w][d].date) {
						this.dateBoxes.push(data[w][d]);
						var index = this.dateBoxes.length - 1;
						data[w][d].selectedIndex = index;
					}
				}
			}
		}
	}
	
	this.selectRange = function(start, end) {
		var step = (start > end)? -1 : 1;
		var range = (start > end)? start - end : end - start;
		var i = start;
		if (range > 27) {
			end = start + 27 * step;
			if (start > end) { end-- };
		}

		var showCheckratesMsg = false;
		do {
			var dateObj = this.dateBoxes[i];
			if (dateObj.cell) {
				this.selectCell(dateObj.cell);
			}
			if (dateObj.isSoldOut || dateObj.isRestricted) {
				showCheckratesMsg = true;
			}
			i += step;			
		} while (i != (end + step)) 
	
		return i - step;
	}
	
	this.getDateLabel = function(date) {
		if (date) {
			return WEEKDAYS[date.getDay()] + ", "
				+ MONTHS[date.getMonth()] + " " 
				+ date.getDate() + ", " 
				+ date.getFullYear();
		} else {
			return "Not Selected";
		}
	}
	
	this.updateCiLabel = function(date) {
		var ciDate = (date)?date:this.newCiDate;
		this.ciLabel.innerHTML = this.getDateLabel(ciDate);
	}
	
	this.updateCoLabel = function(date) {
		var coDate = (date)?date:this.newCoDate;
		this.coLabel.innerHTML = this.getDateLabel(coDate);
	}
	
	this.updateStayLabel = function() {
		this.updateCiLabel();
		this.updateCoLabel();
	}
	
	this.resetDates = function() {
		this.newCiDate = this.ciDate;
		this.newCoDate = this.coDate;
		this.monthIndex = this.ciIndex;
		this.updateStayLabel();
		this.resetSelected();
		if (this.isVisible()) {
			this.initCalendar(true);
		}
	}
	
	this.selectDates = function(ciDate,coDate) {
		this.newCiDate = ciDate;
		this.newCoDate = coDate;
		this.updateStayLabel();
		this.resetSelected();			
	}
	
	this.getRateDate = function(dayObj) {
		if (!dayObj.dateObj) {
			dayObj.dateObj = new Date(dayObj.year, dayObj.month - 1, dayObj.date); 
		}
		return dayObj.dateObj; 
	}

	Hotels.RoomRateCalendarManager.register(this);
}


