/*
 * BE common functions
 *
 * C 2009 Open Hospitality, Inc.  All rights reserved.
 */

$(document).ready(function() {
	var inline = (typeof(BE.inline) == "undefined")? 0:1;
});

EventObject = function() { };

EventObject.prototype = {

    _eventList: {},
    _getEvent: function(eventName, create) {
        // Check if Array of Event Handlers has been created
        if (!this._eventList[eventName]) {

            // Check if the calling method wants to create the Array
            // if not created. This reduces unneeded memory usage.
            if (!create) {
                return null;
            }

            // Create the Array of Event Handlers
            this._eventList[eventName] = []; // new Array
        }

        // return the Array of Event Handlers already added
        return this._eventList[eventName];
    },
    attachEvent: function(eventName, handler) {
        // Get the Array of Event Handlers
        var evt = this._getEvent(eventName, true);

        // Add the new Event Handler to the Array
        evt.push(handler);
    },
    detachEvent: function(eventName, handler) {
        // Get the Array of Event Handlers
        var evt = this._getEvent(eventName);

        if (!evt) { return; }

        // Helper Method - an Array.indexOf equivalent
        var getArrayIndex = function(array, item) {
            for (var i = array.length; i < array.length; i++) {
                if (array[i] && array[i] === item) {
                    return i;
                }
            }
            return -1;
        };

        // Get the Array index of the Event Handler
        var index = getArrayIndex(evt, handler);

        if (index > -1) {
            // Remove Event Handler from Array
            evt.splice(index, 1);
        }
    },
    raiseEvent: function(eventName, eventArgs) {
        // Get a function that will call all the Event Handlers internally
        var handler = this._getEventHandler(eventName);
        if (handler) {
            // call the handler function
            // Pass in "sender" and "eventArgs" parameters
            handler(this, eventArgs);
        }
    },
    _getEventHandler: function(eventName) {
        // Get Event Handler Array for this Event
        var evt = this._getEvent(eventName, false);
        if (!evt || evt.length === 0) { return null; }

        // Create the Handler method that will use currying to
        // call all the Events Handlers internally
        var h = function(sender, args) {
            for (var i = 0; i < evt.length; i++) {
                evt[i](sender, args);
            }
        };

        // Return this new Handler method
        return h;
    }
};
 
   
// base class: object collections
var objectcollection = function() {
    var _lsize = 0;

    this._eventList = {};

    this.add = function(newitem) {
        if (newitem == null) return;
        _lsize++;
        this[(_lsize - 1)] = newitem;
        this.raiseEvent("onadditem", newitem);
    }

    this.modifybykey = function(keyname, newitem) {
        if (newitem == null) return;
        for (var i = 0; i < _lsize; i++) {
            if (eval("this[i]." + keyname) == eval("newitem." + keyname)) { this[i] = newitem; break; }
        }
    }

    this.removebyindex = function(index) {
        if (index < 0 || index > this.length - 1) return;
        this[index] = null;
        for (var i = index; i <= _lsize; i++) this[i] = this[i + 1];
        _lsize--;
    }

    this.removebykey = function(keyname, keyvalue) {
        var targetindex = 0;
        for (var i = 0; i < _lsize; i++) {
            if (eval("this[i]." + keyname) == keyvalue) { targetindex = i; break; }
        }
        this.removebyindex(targetindex);
    }

    this.isempty = function() { return _lsize == 0; }

    this.size = function() { return _lsize; }

    this.clear = function() {
        this.raiseEvent("onbeforeclear");
        for (var i = 0; i < _lsize; i++) this[i] = null;
        _lsize = 0;
        this.raiseEvent("onclear");
    }

    this.clone = function() {
        var c = new objectcollection();
        for (var i = 0; i < _lsize; i++) c.add(this[i]);
        return c;
    }

    this.getitembykey = function(keyname, keyvalue) {
        for (var i = 0; i < _lsize; i++) {
            if (eval("this[i]." + keyname) == keyvalue) { return this[i]; break; }
        }
    }

    this.itemexist = function(keyname, item) {
        var rtnvalue = false;
        for (var i = 0; i < _lsize; i++) {
            if (eval("this[i]." + keyname) == eval("item." + keyname)) { rtnvalue = true; break; }
        }
        return rtnvalue;
    }
};

objectcollection.prototype = new EventObject();


// class: shoppingcart
var shoppingcart = function() {

    this.nextlinenumber = function() {
        if (this.size() == 0) { return 1; }
        else {
            var maxlinenumber = this[0].linenumber;
            for (var i = 1; i < this.size(); i++) {
                if (this[i].linenumber > maxlinenumber) { maxlinenumber = this[i].linenumber; }
            }
            return parseInt(maxlinenumber) + 1;
        }
    }

    this.tojson = function() {
        var citemarray = new Array();
        for (var i = 0; i < this.size(); i++) {
            var citem = new shoppingcartitem(this[i]);
            citemarray.push(citem.tojson());
        }
        var rtnvalue = '{"cartitems":[' + citemarray.join(",") + ']}';
        return rtnvalue;
    }

    this.totalrates = function() {
        var _totalrates = 0.0;
        for (var i = 0; i < this.size(); i++) { _totalrates += this[i].rates; }
        return _totalrates;
    }

    this.totalpackages = function() {
        var _totalpackages = 0.0;
        for (var i = 0; i < this.size(); i++) { _totalpackages += jLinq.from(this[i].packages).sum("rates").result; }
        return _totalpackages;
    }

    this.totaltaxes = function() {
        var _totaltaxes = 0.0;
        for (var i = 0; i < this.size(); i++) { _totaltaxes += (this[i].taxes + jLinq.from(this[i].packages).sum("taxes").result); }
        return _totaltaxes;
    }

    this.totalbooking = function() {
        var _totalbooking = 0.0;
        for (var i = 0; i < this.size(); i++) { _totalbooking += (this[i].total + jLinq.from(this[i].packages).sum("total").result); }
        return _totalbooking;
    }    
};

shoppingcart.prototype = new objectcollection();


// class: packagecollection
var packagecollection = function() {
    this.tojson = function() {
        var pitemarray = new Array();
        for (var i = 0; i < this.size(); i++) {
            var pitem = new packagecartitem(this[i]);            
            pitemarray.push(pitem.tojson());
        }
        return '{"packages":[' + pitemarray.join(",") + ']}';
    }
};

packagecollection.prototype = new objectcollection();


// class: shoppingcartitem 
// utility: tojson()
var shoppingcartitem = function(citem) {

    this.tojson = function() {
        var kvarray = new Array();
        for (property in citem) {
            if (property == "raterange" || property == "packages") {
                kvarray.push('"' + property + '":' + JSON.stringify(eval("citem." + property))); 
            }
            else {
                kvarray.push('"' + property + '":"' + eval("citem." + property) + '"'); 
            }            
        }
        return "{" + kvarray.join(",") + "}";
    }
};


// class: packagecartitem
// utility: tojson()
var packagecartitem = function(pitem) {  
  
    this.tojson = function() {    
        var kvarray = new Array();
        for (property in pitem) {
            kvarray.push('"' + property + '":"' + eval("pitem." + property) + '"'); 
        }        
        return "{" + kvarray.join(",") + "}";
    }
};


// return single result strict
var getsinglequeryresultstrict = function(queryset, querykey, queryvalue) {
    return jLinq.from(queryset).ignoreCase().equals(querykey, queryvalue).select()[0];
};

// return single result
var getsinglequeryresult = function(queryset, querykey, queryvalue) {
    return jLinq.from(queryset).ignoreCase().contains(querykey, queryvalue).select()[0];
};


// return result set
var getqueryresults = function(queryset, querykey, queryvalue) {
    return jLinq.from(queryset).ignoreCase().contains(querykey, queryvalue).select();
};


// stay object
var stay = function(stayid, stays) {
    return getsinglequeryresultstrict(stays, "stayid", stayid);
};


// rate object
var rate = function(rateid, hotelrates) {
    return getsinglequeryresult(hotelrates, "rateid", rateid);
};


// room object
var room = function(roomid, hotelrooms) {
    return getsinglequeryresult(hotelrooms, "roomid", roomid);
};


// promo object 
var promo = function(promocode, hotelpromocodes) {
    return getsinglequeryresultstrict(hotelpromocodes, "promocode", promocode);
};


// inventory object
var inventory = function(inventoryid, hotelinventories) {
    return getsinglequeryresult(hotelinventories, "inventoryid", inventoryid);
};


// cancel policy object
var cancelpolicy = function(cancelpolicyid, hotelcancelpolicies) {
    return getsinglequeryresult(hotelcancelpolicies, "cancelpolicyid", cancelpolicyid);
};


var packagegroup = function(categoryid, packagegroups) {
    return getsinglequeryresult(packagegroups, "categoryid", categoryid);
};


// package item object
var packageitem = function(itemid, packageitems) {
    return getsinglequeryresult(packageitems, "itemid", itemid);
};


// current stay object
var currentstay = function(stayid, roomstays) {

    var _stay = new stay(stayid, roomstays.stays);
    var _rate = new rate(_stay.rateid, BE.hotelrates);
    var _room = new room(_stay.roomid, BE.hotelrooms);
    var _inventory = new inventory(_stay.inventoryid, BE.hotelinventories);
    var _cancelpolicy = new cancelpolicy(_stay.cancelpolicyid, BE.hotelcancelpolicies);

    var _promo;
    var _pkgpromo;
    if (_stay.promocode.length === 0) {
        _promo = new promo('__default' + BE.hotelinfo.hotelid, BE.hotelpromocodes);
    }
    else {
        var _promo = new promo(_stay.promocode, BE.hotelpromocodes);
        _room.maxroomadultoccu = _promo.maxoccupancy != 0 ? _promo.maxoccupancy : _room.maxroomadultoccu;
        _room.minroomadultoccu = _promo.minoccupancy != 0 ? _promo.minoccupancy : _room.minroomadultoccu;
    }
    if (_stay.pkgpromocode.length === 0) {
        _pkgpromo = new promo('__default' + BE.hotelinfo.hotelid, BE.hotelpromocodes);
        //_pkgpromo = _promo;
    }
    else {
        _pkgpromo = new promo(_stay.pkgpromocode, BE.hotelpromocodes);
        //if (typeof _pkgpromo.promoid === "undefined") { _pkgpromo = new promo('__default' + BE.hotelinfo.hotelid, BE.hotelpromocodes); };
    }
    //_pkgpromo = new promo(_rate.packagingpromo, roomstays.promocodes);
    var _etrasitemids = jLinq.from(_pkgpromo.promoextras).distinct("etrasitemid");
    var _packageitems = jLinq.from(BE.hotelpackageitems).contains("itemid", _etrasitemids).select();
    _packageitems = jLinq.from(_packageitems).join(_pkgpromo.promoextras, "promoextra", "itemid", "etrasitemid")
        .select(function(packageitem) {
            packageitem.itemid = packageitem.promoextra.etrasitemid;
            packageitem.optional = packageitem.promoextra.optional;
            packageitem.priceoverride = packageitem.promoextra.priceoverride;
            packageitem.tax = (packageitem.priceoverride + packageitem.additionalunitamount + packageitem.servicechargepercent) * packageitem.taxrate / 100 + packageitem.additionalflattax;
            return packageitem;
        });

    var _packagegroupitems = jLinq.from(_packageitems).orderBy("categorydisplayorder").groupBy("categoryid")
        .select(function(r) {
            return {
                group: new packagegroup(r.key, BE.hotelpackagegroups),
                items: jLinq.from(r.items).orderBy("displayorder").select()
            };
        });

    return {
        "stay": _stay,
        "rate": _rate,
        "room": _room,
        "promo": _promo,
        "inventory": _inventory,
        "cancelpolicy": _cancelpolicy,
        "packageitems": _packageitems,
        "packgroupitems": _packagegroupitems
    }

};


var CCRecord = function() {
    this.ccguestid = null;
    this.ccid = null;
    this.cctype = null;
    this.cctypedesc = null;
    this.ccnumber = null;
    this.ccexpmonth = null;
    this.ccexpyear = null;
    this.ccbillingname = null;
    this.ccbillingaddress = null;
    this.removeccinfo = null;
};


var isvalidemailaddress = function(emailAddress) {
    var pattern = new RegExp(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i);
    return pattern.test(emailAddress);
};


var isvalidbrowser = function() {
    var rtnvalue = true;
    $.each($.browser, function(i) {
        if ($.browser.msie) {
          if ($.browser.version != '7.0' && $.browser.version != '8.0' && $.browser.version != '9.0') rtnvalue = false;
		
        }
    });
    return rtnvalue;
};


var ccErrorNo = 0;
var ccErrors = new Array()

ccErrors[0] = "No card number provided";
ccErrors[1] = "Credit card number is in invalid format";
ccErrors[2] = "Credit card number is invalid";
ccErrors[3] = "Credit card number has an inappropriate number of digits";

var checkcreditcard = function(cardnumber, cardtype) {
    // Array to hold the permitted card characteristics
    var cards = new Array();

    // Define the cards we support. You may add addtional card types.

    //  Name:      As in the selection box of the form - must be same as user's
    //  Length:    List of possible valid lengths of the card number for the card
    //  prefixes:  List of possible prefixes for the card
    //  checkdigit Boolean to say whether there is a check digit

    cards[1] = { name: "AmEx", length: "15", prefixes: "34,37", checkdigit: true };
    cards[3] = { name: "DinersClub", length: "14,16", prefixes: "300,301,302,303,304,305,36,38,55", checkdigit: true };
    cards[4] = { name: "Discover", length: "16", prefixes: "6011,65", checkdigit: true };  
    cards[5] = { name: "MasterCard", length: "16", prefixes: "51,52,53,54,55", checkdigit: true };    
    cards[6] = { name: "Visa", length: "13,16", prefixes: "4", checkdigit: true };
    cards[7] = { name: "JCB", length: "15,16", prefixes: "35,1800,2131", checkdigit: true };
    cards[8] = { name: "enRoute", length: "15", prefixes: "2014,2149", checkdigit: true };
    cards[9] = { name: "Solo", length: "16,18,19", prefixes: "6334, 6767", checkdigit: true };
    cards[10] = { name: "Switch", length: "16,18,19", prefixes: "4903,4905,4911,4936,564182,633110,6333,6759", checkdigit: true };
    cards[11] = { name: "Maestro", length: "16,18", prefixes: "5020,5038,6304,6759", checkdigit: true };
                    
    // Ensure that the user has provided a credit card number
    if (cardnumber.length == 0) {
        ccErrorNo = 0;
        return false;
    }

    // Now remove any spaces from the credit card number
    cardnumber = cardnumber.replace(/\s/g, "");

    // Check that the number is numeric
    var cardNo = cardnumber
    var cardexp = /^[0-9]{13,19}$/;
    if (!cardexp.exec(cardNo)) {
        ccErrorNo = 1;
        return false;
    }

    // Now check the modulus 10 check digit - if required
    if (cards[cardtype].checkdigit) {
        var checksum = 0;                                  // running checksum total
        var mychar = "";                                   // next char to process
        var j = 1;                                         // takes value of 1 or 2

        // Process each digit one by one starting at the right
        var calc;
        for (i = cardNo.length - 1; i >= 0; i--) {

            // Extract the next digit and multiply by 1 or 2 on alternative digits.
            calc = Number(cardNo.charAt(i)) * j;

            // If the result is in two digits add 1 to the checksum total
            if (calc > 9) {
                checksum = checksum + 1;
                calc = calc - 10;
            }

            // Add the units element to the checksum total
            checksum = checksum + calc;

            // Switch the value of j
            if (j == 1) { j = 2 } else { j = 1 };
        }

        // All done - if checksum is divisible by 10, it is a valid modulus 10.
        // If not, report an error.
        if (checksum % 10 != 0) {
            ccErrorNo = 2;
            return false;
        }
    }

    // The following are the card-specific checks we undertake.
    var LengthValid = false;
    var PrefixValid = false;
    var undefined;

    // We use these for holding the valid lengths and prefixes of a card type
    var prefix = new Array();
    var lengths = new Array();

    // Load an array with the valid prefixes for this card
    prefix = cards[cardtype].prefixes.split(",");

    // Now see if any of them match what we have in the card number
    for (i = 0; i < prefix.length; i++) {
        var exp = new RegExp("^" + prefix[i]);
        if (exp.test(cardNo)) PrefixValid = true;
    }

    // If it isn't a valid prefix there's no point at looking at the length
    if (!PrefixValid) {
        ccErrorNo = 2;
        return false;
    }

    // See if the length is valid for this card
    lengths = cards[cardtype].length.split(",");
    for (j = 0; j < lengths.length; j++) {
        if (cardNo.length == lengths[j]) LengthValid = true;
    }

    // See if all is OK by seeing if the length was valid. We only check the 
    // length if all else was hunky dory.
    if (!LengthValid) {
        ccErrorNo = 3;
        return false;
    };

    // The credit card is in the required format.
    return true;
};


// add commas to format number
var addcommas = function(nStr) {
    nStr += '';
    x = nStr.split('.');
    x1 = x[0];
    x2 = x.length > 1 ? '.' + x[1] : '';
    var rgx = /(\d+)(\d{3})/;
    while (rgx.test(x1)) { x1 = x1.replace(rgx, '$1' + ',' + '$2'); }    
    return x1 + x2;
}


/*** utility functions ***/

var HandleFormSubmitAtions = function(formID) {
    $(formID).keypress(function(e) {
        if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
            $(formID + ' input[type=submit]').trigger('click');
            return true;
        }
        else if ((e.which && e.which == 27) || (e.keyCode && e.keyCode == 27)) {
            $(formID + ' #cancel').trigger('click');
            return true;
        }        
    });
};


var showopaquelayer = function() {
    //$('#opaquelayer').css({ "display": "" });
    $('#opaquelayer').css({ "display": "", width: $(document).width(), height: $(document).height() });
};

var hideopaquelayer = function() { $('#opaquelayer').css({ "display": "none" }); };


var createnavigationbar = function() {

    // remove all steps except check availability request and special sign up
    while ($('#steps form').length > 2) { $($('#steps form')[1]).remove(); }

    // reset html contents for step 1
    $($($('#steps form')[0]).find('span')[0]).html(BE.hotelstringresources.$$STEP_LABEL_CHECK_AVAILABILITY);

    $($($('#steps form')[0]).find('button')[0]).addClass('pastbutton');

    // recreate steps next except check availability request
    $('#steps').append($('#navigation_steps_temp').parsetemplate(BE.hotelstringresources));        

    // hide 'Package' step
    $('#steppackages').hide();

};


var createmultiroomoption = function() {

    // setup cookie value for use in the rooms page
    $('#supports_multi_room').val("1");

    var adults = $(".pdadults").clone();
    var adultsselect = $(".pdadultsselect").clone();
    var children = $(".pdchildren").clone();
    var childrenselect = $(".pdchildrenselect").clone();

    $(".pdadults").remove();
    $(".pdadultsselect").remove()
    $(".pdchildren").remove();
    $(".pdchildrenselect").remove();
    $('.information').remove();

    var room = '<td class="pdrooms"><label for="pdrooms">' + BE.hotelstringresources.$$MR_DATES_LABEL_ROOMQTY + '</label></td>';
    var roomselect = '<td class="pdroomsselect" colspan="3"><select id="pdrooms" title="Rooms" name="pdrooms"></select></td>';
    var multiroomnotice = '<td class="pdmultiroomnotice" colspan="4"><span>' + BE.hotelstringresources.$$MR_DATES_SUPRESS_ADULTS_CHILD + '.</span></td>';
    $($('#controls tr')[1]).append(room).append(roomselect);

    for (i = 1; i <= BE.hotelinfo.maxroomsinbooking; i++) { $('#pdrooms').append("<option value=0" + i + ">" + i + "</option>"); }

    $($('#controls tr')[2]).append(adults).append(adultsselect).append(children).append(childrenselect).append(multiroomnotice);

    $(".pdmultiroomnotice").hide();

    $('#pdrooms').change(function() {
        if (parseInt($('#pdrooms').val(), 10) != 1) {
            $(".pdmultiroomnotice").show();
            $(".pdadults").hide();
            $(".pdadultsselect").hide();
            $(".pdchildren").hide();
            $(".pdchildrenselect").hide();
        }
        else {
            $(".pdmultiroomnotice").hide();
            $(".pdadults").show();
            $(".pdadultsselect").show();
            $(".pdchildren").show();
            $(".pdchildrenselect").show();
        }
    });

};


var iniroompage = function(roomstays, multirooms) {

    // recreate navigation bar
    createnavigationbar();

    // set current step to roomrates
    $('#steproomrates').addClass('current');

    // remove "disable" attribute
    $('#steproomrates button').removeAttr("disabled");

    $('#steps button').mouseover(function() {
        if (!$(this).parent().hasClass('current')) { $(this).find("span").addClass('hover'); }
    }).mouseout(function() {
        $(this).find("span").removeClass('hover');
    });

    // summarybox base template: a fieldset
    $('#summary').empty().html($('#summarybox_base_temp').parsetemplate({}));

    // summarybox "edit dates" button
    $('#summarydatesheader button').click(function() {

		//if room is not selected do not show warning
		if ($('#summaryroomguests').length == 0)
		{
			$($('#steps button')[0]).trigger('click');
		}
		else {
			$('body').popupwarning({
				warningheader: BE.hotelstringresources.$$LABEL_NOTE,
				warningmessage: BE.hotelstringresources.$$MESSAGE_DATA_WILL_BE_LOST,
				showhyperlink: true,
				buttondisplaytext: BE.hotelstringresources.$$BUTTON_OK,
				hyperlinkdisplaytext: BE.hotelstringresources.$$BUTTON_CANCEL,
				onload: function() { showopaquelayer(); },
				onclose: function() { hideopaquelayer(); },
				onhyperlinkclick: function() { hideopaquelayer(); },
				onbuttonclick: function() {
					$($('#steps button')[0]).trigger('click');
					hideopaquelayer();
				}
			});		
		}
        return false;
    });

    $('.roomstaysheader .stayselect').html(BE.hotelstringresources.$$LABEL_ROOM);

    // remove the form for each room stay
    $('.stayselect').each(function() {
        if (typeof $(this).find('fieldset')[0] != "undefined") {
            var fieldsetclone = $($(this).find('fieldset')[0]).clone();
            $($(this).find('form')[0]).remove();
            $(this).append(fieldsetclone);
        }
    });

    if (multirooms) {
        // replace select button to add button
        $('.stayselect button').attr("title", BE.hotelstringresources.$$BUTTON_ADD);
        $('.stayselect button span').html(BE.hotelstringresources.$$BUTTON_ADD);

        var mrbehelp = $('#mrbehelp_temp').parsetemplate({});
        $(mrbehelp).insertAfter('#multistay fieldset legend').click(function() {
            $('body').popuphelp({ templateid: '#mr_behelp_rooms_temp' });            
            return false;
        });

        applyroomquantity(roomstays);
    }
    
		// case 50822, 55899 - Google Analytics tracking
		if (typeof(_gaq) !== "undefined" ) {
			_gaq.push(['_trackPageview', 'ibe_rooms.aspx']);
			//alert('gaq test init load - ibe_rooms.aspx');
		}

};


var applyroomquantity = function(roomstays) {
    
    // apply quantity change box to each add button
    $('.stayselect button').quantitychangebox({ defaultvalueasdash: true });
    
    // add button onclick event
    $('.stayselect button').each(function() {
        var stayid = $(this).siblings("input").attr("value");
        var mystay = new stay(stayid, roomstays.stays);
        var myroomnum = roomstays.availabilityrequest.maxroomqty != 1 ? Math.min(roomstays.availabilityrequest.maxroomqty, mystay.availableqty) : mystay.availableqty;
        $(this).siblings("div").children("div").children("input").attr("maxlength", myroomnum);
    });
               
};


// re-sequance room number on the room label after room added/removed
// this will only happen while the current step is roomrates
this.resequencyroomnumber = function() {
    if ($('.current').attr("id") == 'steproomrates') {
        for (var i = 1; i <= $("table[summary=Rooms]").length; i++) {
            $($($("table[summary=Rooms]")[i - 1]).find("th")[0]).html(BE.hotelstringresources.$$LABEL_ROOM + '&nbsp;' + i);
        }
    }
};


var showprogress = function(hide, confirmationprogress) {

    if (hide) {
        $('#progress').remove();
        hideopaquelayer();
    }
    else {
        $('#progress').remove();
        if (confirmationprogress) { $('body').append($('#confirmation_progress_temp').parsetemplate({})); }
        else { $('body').append($('#progress_temp').parsetemplate({})); }

        // position the popup on the center of the page
        leftVal = $(window).width() / 2 - ($('#progress').width() / 2); // -$('#bookingengine').offset().left;
        topVal = $(window).height() / 2 - ($('#progress').height() / 2) + $(window).scrollTop(); // -$('#bookingengine').offset().top;

        $('#progress').css({ top: topVal, left: leftVal });
        $('#progress').show();
        showopaquelayer();
    }
};


var iniinlinejson = {
			  "shopper": {
						"guestid": 0,"title": "","firstname": "","lastname": "","companyname": "","iatanumber": "","customfieldids": [],"customfieldvalues": [],"email": "","allowmailings": true,
						"addressinfo": {"address1": "","address2": "","city": "","statecode": "","statedescription": "","postcode": "","countrycode": "","countrydescription": "","phone1": "","phone2": "","fax1": "","fax2": ""},
						"ccinfo": {"cctypeid": -1,"ccnumber": "","ccbillingname": "","ccbillingaddress": "","expiremonth": 1,"expireyear": 1,"isvalid": false},
						"guestcreditcards": [{"id": 0,"isactive": true,"type": "","number": "","expdate": "1/1","billingname": "","billingaddress": ""}],
						"profiles": []
					  }
};


var inisigninoptions = function() {

	var inline = (typeof(BE.inline) == "undefined")? 0:1;
	if (inline == 0) { //popup
			$('body').signinoption({
				onload: function() { showopaquelayer(); },
				onclose: function() { hideopaquelayer(); },
				oncompletereservation: function(jsonresult) { iniregistration(jsonresult, null); },        
				oncreateaccount: function(email) {
				if (document.getElementById("registration") === null) {
					$.ajax({
						data: { 'cmd': 'post', 'psk230': 'psk230', 'task': 'getregistration' },
						success: function(jsonresult) { iniregistration(jsonresult, email); }                
					});
				}
				}
			});
	}
	else { //inline
			var jsonresult = iniinlinejson;
	}
};




var iniregistration = function(jsonresult, guestemail) {
    $('.current').removeClass('current');
    $('#stepguestinfo').addClass('current');
    $('#stepguestinfo button').addClass('pastbutton');

    $('#multistay').hide(); // hide multistay
    $('#packages').remove(); // remove packages

	var inline = (typeof(BE.inline) == "undefined")? 0:1;
	if (inline == 0) { //popup
		// create registration section
		$('<div id="registration"></div>').insertAfter('#multistay');			
	}

    // create a new "complete reservation" button below registration section
    //$(proceeedbutton).appendTo('#registration').click(function() { completereservation() });


    // hide the button below the summarybox
    $('#summary div.stepproceed').hide();

    // change html contents of the proceed button                    
    $('.stepproceed button').each(function() {
        $($(this).find('span')[0]).html(BE.hotelstringresources.$$FORM_CONTROL_COMPLETE_RESERVATION);
    });

    // remove summarybox highlight
    $('.summaryfocus').removeAttr('style').removeClass('summaryfocus');

    try {

//alert("inline - " + inline);

	   var _shopper 
	    if (inline == 0 || guestemail.length > 0) {
			_shopper = JSON.parse(jsonresult).shopper;
		}
		else { 
			_shopper = jsonresult.shopper;
		    // create registration section
		    $('<div id="registration"></div>').insertAfter('#multistay');

		}



        if (typeof _shopper == "undefined") {
            throw "jquery.oh.be.common.js --> function: iniregistration --> _shopper undefined"; 
        }
    }
    catch (e) {
        errorresponsehandler(e, jsonresult);
    }

    // for new guest, assign the email property based on the login pop up.   
    if (guestemail != null && inline == 0) { _shopper.email = guestemail; }

    $('#registration').registermultiroom({
        location: '#registration',
        shopper: _shopper,
        onload: function() { $('html, body').animate({ scrollTop: 0 }, 'fast'); }
    });

    tracking(BE.hotelinfo.hotelid, "&sc=mr1&pg=registration");
}


var completereservationPB = function() {

	if (!(new RegExp("be\.ashx", "i").test(location.toString()))) {
		$("form#completeResForm").attr("action", $("form#completeResForm").attr("action").replace(new RegExp("be\.ashx", "i"), location.toString().split("/").pop().match(new RegExp(".[^?]*")).shift()));
	}

    // required fields validation
    var _formvalidated = true;
    var _errormessage = "";

    // credit card validation for new guest only
    if ($('#guestid').val() == 0 && !checkcreditcard($('#creditcardnumber').val(), $('#creditcardtype').val())) {
        $('#creditcardnumber').addClass('errorfield');
        _formvalidated = false;
        _errormessage = BE.hotelstringresources.$$MESSAGE_INVALID_CC;
    };

    // credit card exp date validation
    var ccexpirationmonth;
    var ccexpirationyear;
    var checkOutDate = new Date(availabilityrequest.checkoutgeneric.toString().substr(0, 4), availabilityrequest.checkoutgeneric.toString().substr(4, 2) - 1, 1);

    if ($('#guestid').val() > 0 && $('#returnguestccinfo').text() != "") {

        if ($('.ccrecords input:radio:checked').val() > 0) {

            $('#guestccinfo').remove();

            //$('.ccrecords input:radio:first').parents('tr').removeClass('errorfield');
            $('.ccrecords table').removeClass('errorfield');

            $('.ccrecords input:radio:checked').parents('tr').each(function() {
                ccexpirationmonth = $(this).find("td:eq(4)").text().split("/")[0] - 1;
                ccexpirationyear = $(this).find("td:eq(4)").text().split("/")[1];
            });

            var ccExpDate = new Date(ccexpirationyear, ccexpirationmonth, 1);
            if (ccExpDate < checkOutDate) {
                $('.ccrecords input:radio:checked').parents('tr').addClass('ccexpired');
                _formvalidated = false;
                _errormessage = BE.hotelstringresources.$$MESSAGE_FILL_REQUIRED_FIELDS;
                $('.ccrecords input:radio:checked').parents('tr').each(function() {
                    $($(this).find("a")).click();
                });
            }
        }
        else {
            _formvalidated = false;
            _errormessage = BE.hotelstringresources.$$MESSAGE_FILL_REQUIRED_FIELDS;
            $('.ccrecords table').addClass('errorfield');
        }
    }
    else {

        $('.ccexpiredmessage').hide();
        ccexpirationmonth = $('#creditcardexpirationmonth').val() - 1;
        ccexpirationyear = $('#creditcardexpirationyear').val();

        var ccExpDate = new Date(ccexpirationyear, ccexpirationmonth, 1);

        if (ccExpDate < checkOutDate) {
            $('#creditcardexpirationmonth, #creditcardexpirationyear').addClass('errorfield');
            $('.ccexpiredmessage').show();
            _formvalidated = false;
            _errormessage = BE.hotelstringresources.$$MESSAGE_FILL_REQUIRED_FIELDS;
        }

        else {
            $('#creditcardexpirationmonth, #creditcardexpirationyear').removeClass('errorfield');
        }
    }

    // confirm password validation for new guest only
    if (!$('#passwordconfirm').attr('readonly') && $('#passwordinitial').val() != $('#passwordconfirm').val()) {
        $('#passwordconfirm').addClass('errorfield');
        _formvalidated = false;
        _errormessage = BE.hotelstringresources.$$MESSAGE_INVALID_PASSWORD;
    };

    $('#registration .regrequired').each(function() {
		if ($(this).attr('id') != 'returnguestemail' &&  $(this).attr('id') != 'returnguestpass') { //ignore login values
			//get input type
			if ($(this).val() == '') {
				$(this).addClass('errorfield');
				_formvalidated = false;
				_errormessage = BE.hotelstringresources.$$MESSAGE_FILL_REQUIRED_FIELDS;
			}
		}
		
	/*	if ($(this).val() != "on") {
			// assumes all checkboxes are nested in div class="checkbox"
			$(this).parent().addClass("errorfield");
			//$('input.checkrequired:checkbox').parent().addClass("errorfield");
			} */
		
    });
	
	$('#registration .checkrequired').each(function() {
							var info = $(this).attr('id');
							var value = $(this).is(":checked");
							
		if (value == false){ 
			$(this).parent().addClass("errorfield");
			_formvalidated = false;
            _errormessage = BE.hotelstringresources.$$MESSAGE_FILL_REQUIRED_FIELDS;
			};
    });

    $('#registration .errorfield').blur(function() {
        if (this.className.indexOf('regrequired') >= 0) {
            if ($(this).val() != '') { $(this).removeClass('errorfield'); }
        }
        else { $(this).removeClass('errorfield'); }
    });


    if (_formvalidated == false) {
        $('#formError').show();
        $('#formError span').html(_errormessage);
        $($('#registration .errorfield')[0]).focus();
        $('html, body').animate({ scrollTop: 0 }, 'fast');
        return false;
    }
    else { $('#formError').hide(); }

    // $('#completeReservation').attr("disabled", "true");

    // guest profiles for each room
    for (i = 0; i < _shoppingcart.size(); i++) {
        var _guestprofile = {};
        _guestprofile.firstname = $('#firstname_' + _shoppingcart[i].staycartid).val();
        _guestprofile.lastname = $('#lastname_' + _shoppingcart[i].staycartid).val();
        _guestprofile.email = $('#email_' + _shoppingcart[i].staycartid).val();
        _guestprofile.specialrequest = $('#specialrequest_' + _shoppingcart[i].staycartid).val();
        _guestprofile.promooption = $('#promooption_' + _shoppingcart[i].staycartid).attr("checked");

        // custom fields
        var guestcsfd = new objectcollection();
        $('#guestprofile' + _shoppingcart[i].staycartid + ' .csfd').each(function() {
            guestcsfd.add({ "id": this.id, "value": $(this).val() });
        });
        _guestprofile.csfd = guestcsfd;

        _shoppingcart[i].guestprofile = _guestprofile;
    }

    // guest details
    primaryguest.guestid = $('#guestid').val();
    primaryguest.title = $('#title').val();
    primaryguest.firstname = $('#firstname').val();
    primaryguest.lastname = $('#lastname').val();
    primaryguest.companyname = $('#companyname').val().replace('&', ' ');
    primaryguest.address = $('#streetaddress').val();
    primaryguest.city = $('#city_js').val();
    primaryguest.state = $('#state_js').val();
    primaryguest.addressother = $('#addressother').val();
    primaryguest.zipcode = $('#zipcode').val();
    primaryguest.country = $('#country').val();
    primaryguest.phone = $('#phone').val();
    primaryguest.fax = $('#fax').val();
    primaryguest.emailaddressinitial = $('#emailaddressinitial').val();
    primaryguest.emailaddressconfirm = $('#emailaddressconfirm').val();
    primaryguest.emailaddressalternate = $('#emailaddressalternate').val();
    primaryguest.passwordinitial = $('#passwordinitial').val();
    primaryguest.passwordconfirm = $('#passwordconfirm').val();
    primaryguest.referralsource = $('#referralsource').val();
    primaryguest.referralother = $('#referralother').val();
    primaryguest.promooption = $('#promooption').attr("checked");
    primaryguest.groupspecialrequest = $('#groupspecialrequests').val();

    primaryguest.creditcardid = $('.ccrecords input:radio:checked').val();

    if (primaryguest.guestid > 0 && primaryguest.creditcardid > 0) {

		$('.ccrecords input:radio:checked').parents('tr:eq(0)').each(function() {
            primaryguest.creditcard = $(this).find("td:eq(2)").text();
            primaryguest.creditcardtype = $(this).find("td:eq(2)").text();
            primaryguest.creditcardnumber = $(this).find("td:eq(3)").text();
            primaryguest.creditcardexpirationmonth = $(this).find("td:eq(4)").text().split("/")[0];
            primaryguest.creditcardexpirationyear = $(this).find("td:eq(4)").text().split("/")[1];
            primaryguest.creditcardbillingname = $(this).find("td:eq(5)").text() == ""
                ? primaryguest.firstname + " "
                + primaryguest.lastname
                :
                $(this).find("td:eq(5)").text();
            primaryguest.creditcardbillingaddress = $(this).find("td:eq(7)").text() == ""
                ?
                primaryguest.address + " "
                + primaryguest.city + " "
                + primaryguest.state + ", "
                + primaryguest.zipcode + " "
                + primaryguest.country
                :
                $(this).find("td:eq(7)").text();
            //primaryguest.creditcard = $('#creditcardtype option:selected').text();
        });
    }
    else {

        primaryguest.creditcardid = 0;
        primaryguest.creditcard = $('#creditcardtype option:selected').text();
        primaryguest.creditcardtype = $('#creditcardtype').val();
        primaryguest.creditcardnumber = $('#creditcardnumber').val();
        primaryguest.creditcardexpirationmonth = $('#creditcardexpirationmonth').val();
        primaryguest.creditcardexpirationyear = $('#creditcardexpirationyear').val();
        primaryguest.creditcardbillingname = $('#ccbillingname').val();
        primaryguest.creditcardbillingaddress = $('#ccbillingaddress').val();
    }

    // custom fields
    var shoppercsfd = new objectcollection();
    $('#registration .csfd').each(function() {
        shoppercsfd.add({ "id": this.id, "value": $(this).val() });
    });
    primaryguest.csfd = shoppercsfd;

    $("div#psk230div #pbbookinginfo").attr("value", $('#reservation_temp').parsetemplate({}));
    return true;

};


// server exception handler
var HandleServerErrorResponse = function(ajaxresult) {
    tracking(BE.hotelinfo.hotelid, "&sc=mr1&pg=" + escape(ajaxresult.errormessage).substr(0, 1024));
    showprogress(false);
    $('body').popupwarning({
        warningheader: 'Sorry',
        warningmessage: 'Your reservation could not be processed. Please try again.',
        buttondisplaytext: 'Try Again',
        onload: function() { showopaquelayer(); },
        onclose: function() { $('#steps button[title=Search]').trigger('click'); },
        onbuttonclick: function() { $('#steps button[title=Search]').trigger('click'); }
    });
    return false;
};


// exception handler
var errorresponsehandler = function(e, ajaxresult) {

    var errormsg = null;

    try {
        errormsg = "Error: " + e + "\n";
        errormsg += "From: errorresponsehandler exception \n"
        errormsg += "Number: " + (e.number & 0xffff) + "\n"
        errormsg += "Description: " + e.description + "\n\n"
        
        tracking(BE.hotelinfo.hotelid, "&sc=mr1&pg=" + escape(errormsg).substr(0, 1024));
    }
    catch (e) {
        errormsg = "exceptions from function --> errorresponsehandler";
        
        //alert(errormsg);
        tracking(BE.hotelinfo.hotelid, "&sc=mr1&pg=" + escape(errormsg).substr(0, 1024));
        
        $($('#steps form')[0]).trigger('submit');
    }

    if (typeof JSON.parse(ajaxresult).error != "undefined" && JSON.parse(ajaxresult).error) {

        //alert("exception from server: " + JSON.parse(ajaxresult).errormessage);
        tracking(BE.hotelinfo.hotelid, "&sc=mr1&pg=" + escape(JSON.parse(ajaxresult).errormessage).substr(0, 1024));

        $('body').popupwarning({
            warningheader: "Note",
            warningmessage: "There's been an error in the system, please try again.",
            showhyperlink: false,
            buttondisplaytext: BE.hotelstringresources.$$BUTTON_OK,
            onload: function() { showopaquelayer(); },
            onclose: function() { hideopaquelayer(); },
            onbuttonclick: function() {
                hideopaquelayer();
                $($('#steps button')[0]).trigger('click');
            }
        });

        return false;
    }
};

// ajax error handler
var ajaxerrorhandler = function(request, errorType, errorThrown) {

    var errormsg = null;

    try {
        errormsg = "There was an error on this page.\n\n"
        errormsg += "An internal programming error may keep this page from displaying properly.\n\n"
        errormsg += "error from: ajaxerrorhandler\n"
        errormsg += "request status: " + request.status + "\n"
        errormsg += "request status text: " + request.statusText + "\n"
        errormsg += "error: " + request.responseText + "\n"
        errormsg += "error type: " + errorType + "\n\n"
        
        //alert(errormsg);
        tracking(BE.hotelinfo.hotelid, "&sc=mr1&pg=" + escape(errormsg).substr(0, 1024));

        // handle timeout
        if (errorType == 'timeout') {
            $('body').popupwarning({
                warningheader: "Note",
                warningmessage: "The request timed out, please try again.",
                showhyperlink: false,
                buttondisplaytext: BE.hotelstringresources.$$BUTTON_OK,
                onload: function() { showopaquelayer(); },
                onclose: function() { hideopaquelayer(); },
                onbuttonclick: function() { hideopaquelayer(); }
            });
        }
    }
    catch (e) {
        try {
            errormsg = "error from: ajaxerrorhandler exception \n"
            errormsg += "Error number: " + (e.number & 0xffff) + "\n"
            errormsg += "Description: " + e.description + "\n\n"
            
            //alert(errormsg);
            tracking(BE.hotelinfo.hotelid, "&sc=mr1&pg=" + escape(errormsg).substr(0, 1024));
            
            $($('#steps form')[0]).trigger('submit');
        }
        catch (e) {
            errormsg = "exceptions from function --> ajaxerrorhandler";
            
            //alert(errormsg);
            tracking(BE.hotelinfo.hotelid, "&sc=mr1&pg=" + escape(errormsg));
        }        
    }    
};


var parsestringvariables = function(str, data) {    
    var _tmplCache = {}
    var err = "";
    try {
        var func = _tmplCache[str];
        if (!func) {
            var strFunc =
            "var p=[],print=function(){p.push.apply(p,arguments);};" +
                        "with(obj){p.push('" +
            str.replace(/[\r\t\n]/g, " ")
               .replace(/'(?=[^#]*#>)/g, "\t")
               .split("'").join("\\'")
               .split("\t").join("'")
               .replace(/<#=(.+?)#>/g, "',$1,'")
               .split("<#").join("');")
               .split("#>").join("p.push('")
               + "');}return p.join('');";

            //alert(strFunc);
            func = new Function("obj", strFunc);
            _tmplCache[str] = func;
        }
        return func(data);
    } catch (e) { err = e.message; }
    return "< # ERROR: " + err.toString() + " # >";
};


var tracking = function(hotelid, actionkvps_b) {
    
    var urlarray = [document.URL, window.location.href, document.location.href];
    var myValue = null;

    for (var i = 0; i < urlarray.length; i++) {
        if ((typeof (urlarray[i]) !== "undefined") && (urlarray[i] !== null) && (urlarray[i] !== "")) {
            myValue = urlarray[i];
            break;
        }
    }

    new Image(1, 1).src = "https://www.reservations-page.com/hits.ashx?hits_a=" + hotelid + "&hits_b=" + escape(myValue + actionkvps_b);

	// case 50822, 55899 - Google Analytics tracking
	if (typeof(_gaq) !== "undefined" ) {
		var pagetopush = actionkvps_b.replace('&sc=mr1&', '');
		pagetopush = pagetopush.replace('pg=', 'ibe_') + '.aspx';
		pagetopush = pagetopush.replace('ibe_registration', 'ibe_register');
		pagetopush = pagetopush.replace('ibe_confirmation', 'ibe_confirm');
		_gaq.push(['_trackPageview', pagetopush]);
		//alert('gaq test click event - ' + pagetopush);
	}
};

var handleCCExpired = function(ccexpmonthID, ccexpyearID, controlDate) {

    var ccexpmonth = $(ccexpmonthID).val();
    var ccexpyear = $(ccexpyearID).val();
    var ccExpDate = new Date(ccexpyear, ccexpmonth - 1, 1);

    if (ccExpDate < controlDate) {
        $(ccexpmonthID).addClass('errorfield');
        $(ccexpyearID).addClass('errorfield');
        var theFirst = new Date(new Date().getFullYear(), new Date().getMonth(), 1);
        if (ccExpDate < theFirst) {
            $('.ccexpiredmessage').show();
            $('.ccexpiredmessageRes').hide();
        }
        else {
            $('.ccexpiredmessageRes').show();
            $('.ccexpiredmessage').hide();
        }
        return true;
    }
    else {
        $('.ccexpiredmessage, .ccexpiredmessageRes').hide();
        $(ccexpmonthID).removeClass('errorfield');
        $(ccexpyearID).removeClass('errorfield');
        return false;
    }
};

String.prototype.xmlEncode = function () {
	return this.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
};
