/// <reference path="jquery.js" />
/// <reference path="jquery-vsdoc.js" />

// Global Onload 
$(function(){
	
	// On the document load, pre-translate.
    preTranslateAll();
    translateAll();
    OverviewNoDescriptionStyle();	
    
    // Bot Hiding Stuff
    $(".botHidden").each(function() {
        var labelToSet = $(this);
        labelToSet.text(labelToSet.attr("data-text"));
    });
    
});


gSearching = false;
if (typeof HC == "undefined") {
    HC = {};
}
if (typeof HC.Photo == "undefined") {
    HC.Photos = {};
}

// Changing from one tab to another, un-show the previous tab and show the selected one.
// Update #30 Daniel - Changed the code of the method to be exclusive jquery and to have 
// nicer animation between tab changes.
function TabTabsNew(tabId) {
    // allow for tab identification based on element id..
    if (tabId.substring(0, 3) == "tab") {
        tabId = tabId.substring(3);
    }
    // proceed with tabbing..
    if (tabId == "Map" && typeof (mapSource) == 'undefined') {
        $('#tabMap a').addClass("hc_loading");
        setTimeout('TabTabsNew("Map");$("#tabMap a").removeClass("hc_loading");', 1000);
    } else {
        // if tab not already active..
        if (!($("#tab" + tabId).hasClass("active"))) {
            // Show the selected tab div and set the style of the tab
            $("#tabData" + tabId).fadeIn("medium", function () {
                if (jQuery.browser.msie) // Remove the filter for IE
                {
                    var domElem = $(this).children();
                    domElem.find("[style*='filter']").css('filter', '');
                }
            });

            // Hide the previous current tab.
            $("#tabData" + currentTabId).hide();
            $("#tab" + currentTabId).removeClass("active");
            $("#tab" + tabId).addClass("active");

            currentTabId = tabId;

            if (tabId == "Map" && mapSource.length > 0 && !mapAlreadyShown) {
                setMapFrame();
            }

            if (tabId == "Photos") {
                HC.Gallery.photoTabClicked();
            } else {
                // make sure slideshow is not still playing..
                HC.Gallery.otherTabClicked();
            }
        }
    }

    AnalyticsTrackTabChange(tabId);
}

//Tracks when a tab is click in anayltics
function AnalyticsTrackTabChange(tabId) {
    
    if (typeof _gaq != "undefined") {
        _gaq.push(['_trackEvent', 'Tab Click', tabId]);
    } else {
        $(function() {
            if (typeof _gaq != "undefined") {
                _gaq._trackEvent("Tab Click", tabId);
            }
        });
    }        
}

function WriteStartDiv(tabId) { 
    document.write('<div id="tabData');
    document.write(tabId);
    document.write('"');
    
    if (tabId == currentTabId) {
        document.write('>');
    }
    else {
        document.write(' style="' + 'display');
        document.write(':none">');
    }
}

function WriteEndDiv() {
    document.write("</div>");
}

function WriteStartProviderDiv(providerCode) {
    document.write('<div id="data');
    document.write(providerCode);
    document.write('"');
    document.write(' style="overflow:hidden; line-height:1.5em; font-size:12px;" >');
}

function HotelOverview(title, overview) {    
    document.write('<tr><td class = "overviewMenu"><b>' + title + ':</b></td><td class="overviewContent">' + overview + '</td></tr>');
}

function SetOverviewAmenities() {    
    var amenities = $('#amenitiesHidden').val();
    var amenityArray;
    var amenityHtml = "";

    if (amenities != null && amenities != "") {
        amenityArray = amenities.split(",");
        
        var startInt = 0;
        if (amenityArray.length > 0) {
            if (amenityArray[0] == "hasMoreAmenities") {
                startInt = 2;
            }

            amenityHtml += "<ul>";
            for (var i = startInt; i < amenityArray.length; i++) {
                amenityHtml += "<li>" + amenityArray[i] + "</li>";
            }

            if (startInt == 2) {
                amenityHtml += "<li class=\"listTypeNone\"><a href=\"javascript:TabTabsNew('Details')\">" + amenityArray[1] + "</a></li>";
            }
            amenityHtml += "</ul>";

            $('#amenitiesDisplay').html(amenityHtml);
        } 
    }
    else {
        $('#amenitiesTitle').hide();
    }
}

function GetY(theElement) {
    var returnValue = 0;
    while (theElement != null) {
        returnValue += theElement.offsetTop;
        theElement = theElement.offsetParent;
    }
    return returnValue;
}

function SwapImage(imageId, index) { 
    document.getElementById('BigImage').src = imgDomain + "/HI" + imageId.toString() + ".jpg";
    document.getElementById('Viewing').innerHTML = index;
}

function setMapFrame() {
    document.getElementById("mapDiv").innerHTML = "<iframe id=\"mapFrame\" src = \"" + mapSource + "\" scrolling=\"no\" frameborder=\"0\" width=\"740px\" height=\"480px\"></iframe>";
    mapAlreadyShown = true;
}

function getHotelUrl(url, domain) {
    var builder = "<a href='" + ReverseString(url) + "'";
    builder += " target='_blank' rel='nofollow'>" + domain + "</a>";
    document.write(builder);
}


/* Google Ads */
google_afs_ie = 'utf8';
google_afs_oe = 'utf8';
google_afs_ad = 'n5'; // specify the number of ads you are requesting
google_afs_client = 'pub-2258200115238219'; // substitute your client ID
google_afs_adsafe = 'high'; // specify level for filtering non-family-safe ads

/*
* This function is required. It processes the google_ads JavaScript object,
* which contains AFS ads relevant to the user's search query. The name of
* this function <i>must</i> be <b>google_afs_request_done</b>. If this
* function is not named correctly, your page will not display AFS ads.
*/
function google_afs_request_done(google_ads) {
    /*
    * Verify that there are actually ads to display.
    */
    var google_num_ads = google_ads.length;
    if (google_num_ads <= 0) {
        return;
    }

    // ad unit html text
    var narrowAdsOne = "";    

    for (i = 0; i < google_num_ads; i++) {
        var trackLink = google_trackLink + encodeURIComponent(google_ads[i].url);

        // render a narrow ad
        var narrowAds = '<span class="ad_line1">' +
            '<a rel="nofollow" target="_blank" ' +
            'href="' + trackLink + '">' +
            google_ads[i].line1 + '</a></span><br>';
        narrowAds += '<span class="ad_text">' + google_ads[i].line2 + '</span><br>';
        narrowAds += '<span class="ad_text">' + google_ads[i].line3 + '</span><br>';
        narrowAds += '<div class="ad_url"><a rel="nofollow" target="_blank" href="' + trackLink + '">' + google_ads[i].visible_url + '</a></div>';

        // render ads for detail tab
        narrowAdsOne += narrowAds;
    }

    if (displayAds == false || narrowAdsOne == "") {
        document.getElementById('googleAds').style.display = "none";
    }
    else {
        narrowAdsOne = '<div class="ad_header" style="text-align:left"></div>' + narrowAdsOne;
        if (document.getElementById("narrow_ad_unit") != null) {
            document.getElementById("narrow_ad_unit").innerHTML = narrowAdsOne;
        }
        if (document.getElementById("googleAds") != null) {
            document.getElementById('googleAds').style.display = "block";
        }
    }
}
/* End of Google Ads */

////////////////////////////////////////////////////////////////////////////////////////////////////
/// Translation Engine
/// The translation engine will translate any item that has the class translate of type label and an
/// attribute called untranslatedText
/// Example: 
///
/// <label class='translate' translationDisclaimer='Translated by Google'
///        untranslatedText='This is the text in english'
///        invalidTranslationError='No es posible traducir texto'>Translating...</label>
///
/// Required Attributes:
///     class='translate' - only items with this class will be translated.
///     translationDisclaimer - text suffixed to the translation as a disclaimer.
///     untranslatedText - The text to translate, without this text nothing will translate.
///     invalidTranslationError - The message shown when the translation failes for whatever reason


/// Changes here need to be made to the SKYSCANNER version also.

// Call back function for when loading is complete
function initialize() {
    translateAll();
}


// Pre-translate all the items marked for pre-translation on load completion.
function preTranslateAll() {
    $("label.preTranslate").each(function() {
        var labelToSet = $(this);
        labelToSet.text(labelToSet.attr("data-untranslatedText"));
    });

    // Bind the original click event
    $(".clickToTranslate").click(function() {
        translateById($(this).attr("data-idToTranslate"), $(this));
    });
}

// Translate the item passed in.
function translateById(idToTranslate, translateLink) {
    if (idToTranslate === undefined) {
        // Ignore
    }
    else {
        // Process the translation.
        var labelToTranslate = $("#" + idToTranslate);

        translate(labelToTranslate);
        translateLink.fadeOut("slow");
    }
}

//add stlye to div #tabWrapper to reorganise the overview tab when no description exists.
function OverviewNoDescriptionStyle() {
    if ($('.hotelDescImgRating p').text().length == 0) {
        $('#tabWrapper').addClass('tabWrapperNoDescription');
    }
}

// Translate the lable passed in.
function translate(labelToTranslate) {
    google.language.translate(labelToTranslate.attr("data-untranslatedText"), labelToTranslate.attr("data-translateFrom"), labelToTranslate.attr("data-translateTo"), function(result) {
        if (result.error) {
            labelToTranslate.fadeTo("slow", 0.1, function() {
                labelToTranslate.text(labelToTranslate.attr("data-invalidTranslationError"));
                labelToTranslate.removeClass("translate");
                labelToTranslate.fadeTo("slow", 1);
            });
        }
        else {
            labelToTranslate.fadeTo("slow", 0.1, function() {
                labelToTranslate.text(result.translation + " - " + labelToTranslate.attr("data-translationDisclaimer"));
                labelToTranslate.removeClass("translate");
                labelToTranslate.fadeTo("slow", 1);
            });
        }
    });
}

// Function to translate all unstranslated items.
function translateAll() {
    $("label.translate").each(function() {
        var labelToSet = $(this);
        translate(labelToSet);
    });
}

// HC Photo Gallery
HC.Gallery = {
    galleryPhotos: Array(),
    currentPhotoNum: 0,
    slideShowTimer: null,
    translations: Array(),

    // initialisation of HC.Gallery.
    initialise: function () {
        // if required, preload images here.

        // if first time on tab, load thumbnails and first main image.
        if (this.isFirstTime()) {
            // load first main image..
            HC.Gallery.loadFirstMainImg();
            // load thumbnails..
            HC.Gallery.loadThumbs();
        }
    },

    // unload of photos tab.
    unload: function () {
        HC.Gallery.pauseSlideShow();
    },

    loadThumbs: function () {
        i = 0;
        $("#mainThumbnailScroll ul li a img").each(
            function (obj) {
                this.src = HC.Gallery.galleryPhotos[i]["thumbnail"];
                i++;
            }
        );
    },

    loadFirstMainImg: function () {
        if (typeof (HC.Gallery.galleryPhotos[0]) != 'undefined') {
            $('#mainPhoto').parent('a').css('background-image', 'url(' + HC.Gallery.galleryPhotos[0]["photo"] + ")");
            $("#mainPhoto").attr("src", HC.Gallery.galleryPhotos[0]["photo"]);
        } 
    },

    isFirstTime: function () {
        try {
            if ($("#mainPhoto").attr("src") == null || $("#mainPhoto").attr("src") == "") {
                return true;
            } else {
                return false;
            }
        } catch (exception) {
            return true;
        }
    },

    addTranslation: function (key, translation) {
        this.translations[key] = translation;
    },

    // add photo to the gallery array containing all photos in the gallery..
    addPhoto: function (myTitle, myPhotoUrl, myThumbnailUrl, myCaption) {
        i = HC.Gallery.galleryPhotos.length;
        HC.Gallery.galleryPhotos[i] = Array();
        HC.Gallery.galleryPhotos[i]["title"] = myTitle;
        HC.Gallery.galleryPhotos[i]["photo"] = myPhotoUrl;
        HC.Gallery.galleryPhotos[i]["thumbnail"] = myThumbnailUrl;
        HC.Gallery.galleryPhotos[i]["caption"] = myCaption;
    },

    photoTabClicked: function () {
        // initialise
        HC.Gallery.initialise();
    },

    otherTabClicked: function () {
        // uninitialise
        HC.Gallery.unload();
    },

    // when a user clicks on the next button..
    next: function () {
        HC.Gallery.pauseSlideShow();
        HC.Gallery.nextPhoto();
    },

    // when a user clicks on the prev button..
    previous: function () {
        HC.Gallery.pauseSlideShow();
        HC.Gallery.prevPhoto();
    },

    // navigate to next photo..
    nextPhoto: function () {
        HC.Gallery.currentPhotoNum++;
        if (HC.Gallery.currentPhotoNum > HC.Gallery.galleryPhotos.length - 1) {
            HC.Gallery.currentPhotoNum = 0;
        }
        HC.Gallery.setPhoto();
    },

    // navigate to previous photo..
    prevPhoto: function () {
        HC.Gallery.pauseSlideShow();
        HC.Gallery.currentPhotoNum--;
        if (HC.Gallery.currentPhotoNum < 0) {
            HC.Gallery.currentPhotoNum = HC.Gallery.galleryPhotos.length - 1;
        }
        HC.Gallery.setPhoto();
    },

    // reset thumbnails to not have an active state..
    resetThumbnails: function () {
        $('#hotelPhotoTd .active').removeClass("active");
    },

    // display current main photo..
    setPhoto: function (myPhotoNum) {
        try {
            if (myPhotoNum != null) {
                HC.Gallery.currentPhotoNum = myPhotoNum;
            }
            // first stop any animations that haven't finished yet, from previous clicks..
            $('#mainPhotoWrap').stop();
            $('#mainPhoto').stop();
            // reset all thumbnails to be inactive..
            HC.Gallery.resetThumbnails();
            // while preloading image, start fade out to show something's happening..
            $('#mainPhotoWrap').animate({ "opacity": "0" }, 5000);
            // make thumbnail active..
            $('#thumb' + HC.Gallery.currentPhotoNum).addClass("active");
            // scroll to thumbnail if it is not visible..
            HC.Gallery.scrollToThumbnail();
            // set viewing image number..
            document.getElementById("viewingPhotoNumber").innerHTML = HC.Gallery.currentPhotoNum + 1;
            // make sure image is preloaded before starting animation effect..
            if ($.browser.msie) { // use .ready instead of .load for ie.
                $('<img />')
                    .attr('src', HC.Gallery.galleryPhotos[HC.Gallery.currentPhotoNum]['photo'])
                    .ready(function () {
                        HC.Gallery.transitionPhoto();
                    });
            } else {
                $('<img />')
                    .attr('src', HC.Gallery.galleryPhotos[HC.Gallery.currentPhotoNum]['photo'])
                    .load(function () {
                        HC.Gallery.transitionPhoto();
                    });
            }
        } catch (exception) {
            //alert("nup: " + exception);
        }
    },

    transitionPhoto: function () {
        // cancel animation on wrapper first then proceed..
        $('#mainPhotoWrap').stop();
        $('#mainPhotoWrap').animate({ "opacity": "1" }, 200);
        // initialise transition effect..
        $('#mainPhotoWrap').addClass('initMainPhoto');
        $('#mainPhoto').css('opacity', '0'); // needs to be inline style.
        $('#mainPhoto').css('filter', 'alpha(opacity=0)'); // needs to be inline style.
        // begin animation effect..
        $('#mainPhoto').attr('src', HC.Gallery.galleryPhotos[HC.Gallery.currentPhotoNum]['photo']);
        $('#mainPhoto').animate({ "opacity": "1" }, "600")
            .show("fast", function () {
                // change background on link element to be same image, so next transition is smooth..
                $('#mainPhoto').parent('a').css('background-image', 'url(' + HC.Gallery.galleryPhotos[HC.Gallery.currentPhotoNum]['photo'] + ')');
                // remove transition required styles..
                $('#mainPhotoWrap').removeClass('dropShadow');
                $('#mainPhotoWrap').removeClass('initMainPhoto');
            })
            .show("slow", function () {
                // show the shadow again..
                $('#mainPhotoWrap').addClass('dropShadow');
            });
    },

    // start slideshow if not already started..
    slideShow: function () {
        if (this.slideShowTimer == null) {
            this.slideShowTimer = setInterval('HC.Gallery.nextPhoto();', 5000);
            myObj = document.getElementById("slideshowLink");
            myObj.innerHTML = this.translations["PhotoGalleryPauseSlideshow"];
            myObj.setAttribute("title", this.translations["PhotoGalleryPauseSlideshow"]);
        }
    },

    // toggle slideshow on or off..
    toggleSlideShow: function () {
        if (this.slideShowTimer == null) {
            this.slideShow();
        } else {
            this.pauseSlideShow();
        }
    },

    // stop slideshow..
    pauseSlideShow: function () {
        if (this.slideShowTimer != null) {
            clearInterval(this.slideShowTimer);
            this.slideShowTimer = null;
            myObj = document.getElementById("slideshowLink");
            myObj.innerHTML = this.translations["PhotoGalleryStartSlideshow"];
            myObj.setAttribute("title", this.translations["PhotoGalleryStartSlideshow"]);
        }
    },

    // automatically scroll down/up so the specified thumbnail is visible
    scrollToThumbnail: function () {
        // does item require scrolling to get to?
        var scrollerHeight = 412;
        var thumbnailHeight = 70;
        var numColumns = 2;
        var thumbnailGap = 12;
        if (HC.Gallery.currentPhotoNum % numColumns == 0) {
            var currentThumbnailY = (HC.Gallery.currentPhotoNum / numColumns) * (thumbnailHeight + thumbnailGap);
        } else {
            var currentThumbnailY = ((HC.Gallery.currentPhotoNum - HC.Gallery.currentPhotoNum % numColumns) / numColumns) * (thumbnailHeight + thumbnailGap);
        }
        var scrollPosition = document.getElementById("mainThumbnailScroll").scrollTop;
        if (currentThumbnailY < scrollPosition) {
            // need to scroll up to thumbnail..
            $("#mainThumbnailScroll").animate({ scrollTop: currentThumbnailY }, 300);
        } else if (currentThumbnailY > scrollPosition + scrollerHeight - thumbnailHeight) {
            // need to scroll down to thumbnail..
            $("#mainThumbnailScroll").animate({ scrollTop: (currentThumbnailY - (scrollerHeight - (thumbnailHeight + thumbnailGap))) }, 300);
        }
    }

};

/* end photo gallery */


/*
Script: JSON.js - 
Update From: http://www.devpro.it/JSON/files/JSON-js.html

Remember to strip down and remove all unnecessary code

JSON encoder / decoder:	
This object uses good practices to encode/decode quikly and a bit safer(*) every kind of JSON compatible variable.
	
To download last version of this script use this link: <http://www.devpro.it/code/149.html>

Version:
1.4 - modified toDate method, now compatible with milliseconds time too (time or milliseconds/1000)
*/
JSON = new function() {
    this.decode = function() {
        var filter, result, self, tmp;
        if ($$("toString")) {
            switch (arguments.length) {
                case 2:
                    self = arguments[0];
                    filter = arguments[1];
                    break;
                case 1:
                    if ($[typeof arguments[0]](arguments[0]) === Function) {
                        self = this;
                        filter = arguments[0];
                    }
                    else
                        self = arguments[0];
                    break;
                default:
                    self = this;
                    break;
            };
            if (rc.test(self)) {
                try {
                    result = e("(".concat(self, ")"));
                    if (filter && result !== null && (tmp = $[typeof result](result)) && (tmp === Array || tmp === Object)) {
                        for (self in result)
                            result[self] = v(self, result) ? filter(self, result[self]) : result[self];
                    }
                }
                catch (z) { }
            }
            else {
                throw new JSONError("bad data");
            }
        };
        return result;
    };

    this.encode = function() {
        var self = arguments.length ? arguments[0] : this,
			result, tmp;
        if (self === null)
            result = "null";
        else if (self !== undefined && (tmp = $[typeof self](self))) {
            switch (tmp) {
                case Array:
                    result = [];
                    for (var i = 0, j = 0, k = self.length; j < k; j++) {
                        if (self[j] !== undefined && (tmp = JSON.encode(self[j])))
                            result[i++] = tmp;
                    };
                    result = "[".concat(result.join(","), "]");
                    break;
                case Boolean:
                    result = String(self);
                    break;
                case Date:
                    result = '"'.concat(self.getFullYear(), '-', d(self.getMonth() + 1), '-', d(self.getDate()), 'T', d(self.getHours()), ':', d(self.getMinutes()), ':', d(self.getSeconds()), '"');
                    break;
                case Function:
                    break;
                case Number:
                    result = isFinite(self) ? String(self) : "null";
                    break;
                case String:
                    result = '"'.concat(self.replace(rs, s).replace(ru, u), '"');
                    break;
                default:
                    var i = 0, key;
                    result = [];
                    for (key in self) {
                        if (self[key] !== undefined && (tmp = JSON.encode(self[key])))
                            result[i++] = '"'.concat(key.replace(rs, s).replace(ru, u), '":', tmp);
                    };
                    result = "{".concat(result.join(","), "}");
                    break;
            }
        };
        return result;
    };

    this.toDate = function() {
        var self = arguments.length ? arguments[0] : this,
			result;
        if (rd.test(self)) {
            result = new Date;
            result.setHours(i(self, 11, 2));
            result.setMinutes(i(self, 14, 2));
            result.setSeconds(i(self, 17, 2));
            result.setMonth(i(self, 5, 2) - 1);
            result.setDate(i(self, 8, 2));
            result.setFullYear(i(self, 0, 4));
        }
        else if (rt.test(self))
            result = new Date(self * 1000);
        return result;
    };
    
    // Privates
    var c = { "\b": "b", "\t": "t", "\n": "n", "\f": "f", "\r": "r", '"': '"', "\\": "\\", "/": "/" },
		d = function(n) { return n < 10 ? "0".concat(n) : n },
		e = function(c, f, e) { e = eval; delete eval; if (typeof eval === "undefined") eval = e; f = eval("" + c); eval = e; return f },
		i = function(e, p, l) { return 1 * e.substr(p, l) },
		p = ["", "000", "00", "0", ""],
		rc = null,
		rd = /^[0-9]{4}\-[0-9]{2}\-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$/,
		rs = /(\x5c|\x2F|\x22|[\x0c-\x0d]|[\x08-\x0a])/g,
		rt = /^([0-9]+|[0-9]+[,\.][0-9]{1,3})$/,
		ru = /([\x00-\x07]|\x0b|[\x0e-\x1f])/g,
		s = function(i, d) { return "\\".concat(c[d]) },
		u = function(i, d) {
		    var n = d.charCodeAt(0).toString(16);
		    return "\\u".concat(p[n.length], n)
		},
		v = function(k, v) { return $[typeof result](result) !== Function && (v.hasOwnProperty ? v.hasOwnProperty(k) : v.constructor.prototype[k] !== v[k]) },
		$ = {
		    "boolean": function() { return Boolean },
		    "function": function() { return Function },
		    "number": function() { return Number },
		    "object": function(o) { return o instanceof o.constructor ? o.constructor : null },
		    "string": function() { return String },
		    "undefined": function() { return null }
		},
		$$ = function(m) {
		    function $(c, t) { t = c[m]; delete c[m]; try { e(c) } catch (z) { c[m] = t; return 1 } };
		    return $(Array) && $(Object)
		};
    try { rc = new RegExp('^("(\\\\.|[^"\\\\\\n\\r])*?"|[,:{}\\[\\]0-9.\\-+Eaeflnr-u \\n\\r\\t])+?$') }
    catch (z) { rc = /^(true|false|null|\[.*\]|\{.*\}|".*"|\d+|\d+\.\d+)$/ }
};

/************ Bot Hiding Stuff (Attractions) *************/

function getWindowHeight() {
    if (document.all) {
        return document.body.offsetHeight;
    }
    else {
        return document.documentElement.offsetHeight;
    }
}
function getWindowSize() {
    var myWidth = 0;
    var myHeight = 0;
    if (typeof (window.innerWidth) == 'number') {
        //Non-IE
        myWidth = window.innerWidth;
        myHeight = window.innerHeight;
    }
    else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
        //IE 6+ in 'standards compliant mode'
        myWidth = document.documentElement.clientWidth;
        myHeight = document.documentElement.clientHeight;
    }
    else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
        //IE 4 compatible
        myWidth = document.body.clientWidth;
        myHeight = document.body.clientHeight;
    }
    return [myWidth, myHeight];
}

function getScrollXY() {
    var scrOfX = 0;
    var scrOfY = 0;
    if (typeof (window.pageYOffset) == 'number') {
        //Netscape compliant
        scrOfY = window.pageYOffset;
        scrOfX = window.pageXOffset;
    }
    else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
        //DOM compliant
        scrOfY = document.body.scrollTop;
        scrOfX = document.body.scrollLeft;
    }
    else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
        //IE6 standards compliant mode
        scrOfY = document.documentElement.scrollTop;
        scrOfX = document.documentElement.scrollLeft;
    }
    return [scrOfX, scrOfY];
}

function getNumericPortion(str) {
    return str.match(/\d*/);
}

/* code to get absolute element position */
var __isIE = navigator.appVersion.match(/MSIE/);
var __userAgent = navigator.userAgent;
var __isFireFox = __userAgent.match(/firefox/i);
var __isFireFoxOld = __isFireFox &&
   (__userAgent.match(/firefox\/2./i) || __userAgent.match(/firefox\/1./i));
var __isFireFoxNew = __isFireFox && !__isFireFoxOld;

function __parseBorderWidth(width) {
    var res = 0;
    if (typeof (width) == "string" && width != null
                && width != "") {
        var p = width.indexOf("px");
        if (p >= 0) {
            res = parseInt(width.substring(0, p));
        }
        else {
            //do not know how to calculate other 
            //values (such as 0.5em or 0.1cm) correctly now
            //so just set the width to 1 pixel
            res = 1;
        }
    }
    return res;
}

//returns border width for some element
function __getBorderWidth(element) {
    var res = new Object();
    res.left = 0; res.top = 0; res.right = 0; res.bottom = 0;
    if (window.getComputedStyle) {
        //for Firefox
        var elStyle = window.getComputedStyle(element, null);
        res.left = parseInt(elStyle.borderLeftWidth.slice(0, -2));
        res.top = parseInt(elStyle.borderTopWidth.slice(0, -2));
        res.right = parseInt(elStyle.borderRightWidth.slice(0, -2));
        res.bottom = parseInt(elStyle.borderBottomWidth.slice(0, -2));
    }
    else {
        //for other browsers
        res.left = __parseBorderWidth(element.style.borderLeftWidth);
        res.top = __parseBorderWidth(element.style.borderTopWidth);
        res.right = __parseBorderWidth(element.style.borderRightWidth);
        res.bottom = __parseBorderWidth(element.style.borderBottomWidth);
    }

    return res;
}

//returns absolute position of some element within document
function getElementAbsolutePos(element) {
    var res = new Object();
    res.x = 0; res.y = 0;
    if (element !== null) {
        res.x = element.offsetLeft;
        res.y = element.offsetTop;
        
        var offsetParent = element.offsetParent;
        var parentNode = element.parentNode;
        var borderWidth = null;
        
        while (offsetParent != null) {
            res.x += offsetParent.offsetLeft;
            res.y += offsetParent.offsetTop;
            
            var parentTagName = offsetParent.tagName.toLowerCase();
            
            if ((__isIE && parentTagName != "table") ||
                (__isFireFoxNew && parentTagName == "td")) {
                borderWidth = __getBorderWidth(offsetParent);
                res.x += borderWidth.left;
                res.y += borderWidth.top;
            }
            
            if (offsetParent != document.body &&
                offsetParent != document.documentElement) {
                res.x -= offsetParent.scrollLeft;
                res.y -= offsetParent.scrollTop;
            }
            
            //next lines are necessary to support FireFox problem with offsetParent
            if (!__isIE) {
                while (offsetParent != parentNode && parentNode !== null) {
                    res.x -= parentNode.scrollLeft;
                    res.y -= parentNode.scrollTop;

                    if (__isFireFoxOld) {
                        borderWidth = __getBorderWidth(parentNode);
                        res.x += borderWidth.left;
                        res.y += borderWidth.top;
                    }
                    parentNode = parentNode.parentNode;
                }
            }
            
            parentNode = offsetParent.parentNode;
            offsetParent = offsetParent.offsetParent;
        }
    }
    return res;
}


HC.Common.Form = {

    //This function will return from the supplied form element name, all html element types listed in .find().
    //Only if those elements have a "name" attribute. 
    //It will return an object of type {"element name" : "element value"}.
    GetFormValuesObject: function (selector, form) {
        var formValues = {};

        if (form == undefined || form == null || form == "") {
         form = 'form';
        }

     var a = $(form + "")
                    .find(selector + " input,textarea,select,hidden")
                    .serializeArray();
        $.each(a, function () {
            if (formValues[this.name]) {
                if (!formValues[this.name].push) {
                    formValues[this.name] = [formValues[this.name]];
                }
                formValues[this.name].push(this.value || '');
            } else {
                formValues[this.name] = this.value || '';
            }
        });
        return formValues;
    }

}

//Used by the reviews tab on the hotel pages (hotel and searchedhotel)
HC.Reviews = {

    //Submit the info entered by the user to the db using ajax
    SubmitReview: function (options) {
        $.ajax(
            {
                type: "GET",
                url: "/WriteAReview.ashx",
                cache: false,
                dataType: "html",
                data: options,
                success: function (data) {
                    if (data != undefined && data != "") {
                        $("#leaveAReview").replaceWith(data);
                    }
                }
            }
        );
    },

    //Remove the error message displayed
    ClearErrorNotifications: function (eventData) {
        $('#' + eventData.data.id).remove();
    },

    //Validate the users input
    ValidateUserReview: function (options) {

        var errMsg = "<span id='{1}' style='color:red; display:block'>{0}</span>";
        var result = true;

        //check review text
        if (options.UserReview == "") {
            if ($("#ReviewTextError").length == 0) {
                $("p.alignCenter").before(errMsg.replace('{0}', $("#WriteReviewErrorMsg3").val()).replace('{1}', 'ReviewTextError'));
            }
            result = false;
        }

        //check all radio buttons for at least one defined
        if (options.Cleanliness == undefined ||
            options.Facilities == undefined ||
            options.Service == undefined ||
            options.Location == undefined ||
            options.Pricing == undefined ||
            options.Rooms == undefined) {
            if ($("#RatingsError").length == 0) {
                $("p.alignCenter").before(errMsg.replace('{0}', $("#WriteReviewErrorMsg4").val()).replace('{1}', 'RatingsError'));
            }
            result = false;
        }

        return result;
    },

    // Show & Hide Comments (ie all comments and form to input comments)
    CollapseHideUserReviews: function () {

        if ($('a.showReviews').hasClass('showReviewsClosed')) {
            $('a.showReviews')
			.removeClass('showReviewsClosed')
			.text($("#HotelPageAddReviewsOpenReviews").val());
            $('div.commentsWrap').hide();

        } else {

            $('div.commentsWrap').show();
            $('a.showReviews')
			.addClass('showReviewsClosed')
			.text($("#HotelPageAddReviewsCloseReviews").val());

        }

    },

    //Validate and submit the users review, entry point to submitting a users review.
    SubmitUserReview: function (options) {

        var formValues = HC.Common.Form.GetFormValuesObject('div.comments');
        $.extend(true, formValues, options);

        if (HC.Reviews.ValidateUserReview(formValues)) {
            HC.Reviews.SubmitReview(formValues);
        }

        return false;
    },

    //If the supplied value if false, the the "WriteAreview" form and any comments
    //will be modified to display in the whole review tab area.
    ShowFormOnly: function (showRatingsAndSummaries) {
        if (!showRatingsAndSummaries) {
            $("#HotelRatingReviews div.col_2").css('padding', '0 0 0 0');
            $("#HotelRatingReviews div.commentsWrap").css('padding', '0 20px 0 20px');
        }
    }
}



