/* Copyright (c) 2005, Sergey Ivanyuk.  All rights reserved. */

/* Sadly, this is unavoidable. */
var isIE = (navigator.appName.indexOf("Internet Explorer") != -1);


var leftOffset = 0; /* Basically the width of our logo.  Used to
		       * resize the results frame. */

var selectedColor = "#ff8000"; /* Color of criteria selectors that
				    have user selections. */

var nosubmit = true;

/* Get an element by its ID.  Cross-browser. */
function getObject(id)
{
    if (typeof(id) == "object")
	return id;

    try {
      var obj = self.document.getElementById(id);
      if (obj)
        return obj;
      
      obj = window.parent.document.getElementById(id);
      if (obj)
        return obj;
    } catch (e) {
    }
    return null;
}

/* Get an object's style object.  Cross-browser. */
function getStyle(id)
{
    return getObject(id).style;
}

/* Get a document style rules object for a given id.  Cross-browser. */
function getStyleRules(id) {
    var rules;
    var sheet = document.styleSheets[0];
    
    if (sheet.cssRules) {
        /* Mozilla */
        rules = sheet.cssRules;
    } else if (sheet.rules) {
        /* IE */
        rules = sheet.rules;
    } else {
        /* No stylesheets. */
        return false;
    }
        
    var classRe = getObject(id).className + '$';
    var idRe = id + '$';

    /* Iterate all styles and find the one that matches our element. */
    for (var i = 0; i < rules.length; i++) {
        if (rules[i].selectorText.search(idRe) != -1)
            return rules[i].style;
        if (rules[i].selectorText.search(classRe) != -1)
            return rules[i].style;
    }
}

/* Move object to a new position. */
function moveObject(obj, x, y)
{
    var style  = obj.style;
    var xoff, yoff;

    xoff = yoff = 0;

    /* Passed in coordinates are absolute, but the style position may
       not be.  Find the necessary offsets and adjust coordinates if
       necessary. */
    while (obj.offsetParent) {
        xoff += obj.offsetParent.offsetLeft;
        yoff += obj.offsetParent.offsetTop;
        obj = obj.offsetParent;
    }

    style.left = x - xoff;
    style.top = y - yoff;
}

/* Get the absolute X position of an object. */
function getXpos(obj)
{
    var curx = 0;

    if (obj.offsetParent) {
        /* For browsers with these, we have to recursively go through
           them and add up the offsets. */
        while (obj.offsetParent) {
            curx += parseInt(obj.offsetLeft);
            obj = obj.offsetParent;
        }
    } else if (obj.x) { /* Netscape */
        return obj.x;
    }
    return curx;
}

/* Get the absolute Y position of an object. */
function getYpos(obj)
{
    var cury = 0;

    if (obj.offsetParent) {
        /* For browsers with these, we have to recursively go through
           them and add up the offsets. */
        while (obj.offsetParent) {
            cury += obj.offsetTop;
            obj = obj.offsetParent;
        }
    } else if (obj.y) { /* Netscape */
        return obj.y;
    }
    return cury;
}

/* Convert nulls to zeros. */
function zeroNull(obj)
{
    if (obj) {
        return obj;
    }
    return 0;
}

/* Capitalize first letter of each word in a string, and make
   everything else lower case. */
function capitalize(str)
{
    if (str == null)
	return null;

    var ret = "";

    for (var i = 0; i < str.length; i ++) {
        if (i == 0 || (i > 0 && str.charAt(i - 1) == " ")) {
            ret += str.substr(i, 1).toUpperCase();
        } else {
            ret += str.substr(i, 1).toLowerCase();
        }
    }

    return ret;
}

/* Get the width of a box surrounding an element. */
function getBoxWidth(objId)
{
    /* This is quite sad.  Only inline styles are directly accessible,
       so we have to search for a style definition with the right
       id.  */

    var style = getStyle(objId);
    var retval = getObject(objId).offsetWidth;
    var rules = getStyleRules(objId);

    /* If we have inline styles, use those, else use the
       stylesheet. */
    if (style.paddingLeft) 
        retval += parseInt(style.paddingLeft);
    else
        retval += parseInt(zeroNull(rules.paddingLeft));

    if (style.paddingRight)
        retval += parseInt(style.paddingRight);
    else
        retval += parseInt(zeroNull(rules.paddingRight));

    if (style.marginLeft) 
        retval += parseInt(style.marginLeft);
    else
        retval += parseInt(zeroNull(rules.marginLeft));

    if (style.marginRight)
        retval += parseInt(style.marginRight);
    else
        retval += parseInt(zeroNull(rules.marginRight));

    return retval;
}
/* Get the height of a box surrounding an element. */
function getBoxHeight(objId)
{
    /* This is quite sad.  Only inline styles are directly accessible,
       so we have to search for a style definition with the right
       id.  */

    var style = getStyle(objId);
    var retval = getObject(objId).offsetHeight;
    var rules = getStyleRules(objId);

    /* If we have inline styles, use those, else use the
       stylesheet. */
    if (style.paddingTop) 
        retval += parseInt(style.paddingTop);
    else
        retval += parseInt(zeroNull(rules.paddingTop));

    if (style.paddingBottom)
        retval += parseInt(style.paddingBottom);
    else
        retval += parseInt(zeroNull(rules.paddingBottom));

    if (style.marginTop) 
        retval += parseInt(style.marginTop);
    else
        retval += parseInt(zeroNull(rules.marginTop));

    if (style.marginBottom)
        retval += parseInt(style.marginBottom);
    else
        retval += parseInt(zeroNull(rules.marginBottom));

    return retval;
}

/* Get the currently selected list value.  Cross-browser. */
function getListSelection(listId)
{
    /* This seems to work everywhere. */
    var elem = getObject(listId);

    return elem.options[elem.selectedIndex].value;
}

/* Add an option to a list.  Cross-browser. */
function addListOption(listId, name, value)
{
    var list;
    if (typeof(listId) == "string") {
        list = getObject(listId);
    } else {
        list = listId;
    }

    if (list.options && list.options.add) 
        list.options.add(new Option(name, value)); /* IE */
    else
        list.appendChild(new Option(name, value)); /* Others */
}

var selectorStyle;

/* Open a criteria selector and position it at the destination
   (criteria) link's location.  
   
   We also need the event object which caused the popup, so that we
   can prevent the click from bubbling down to the parent element -
   parent element clicks are used to close any open selector.
*/
function openSelector(selectorId, destId, event)
{
    var selector = getObject(selectorId);
    var dest = getObject(destId);

    closeSelector(0);

    event.cancelBubble = true; 

    var x, y, width;

    x = getXpos(dest);
    y = getYpos(dest);

    if (false) { // getBoxWidth(selectorId) < dest.offsetWidth) {
        /* Selector's box width should take up the element width of
           our link. */
        width = 
            (dest.offsetWidth 
             - (getBoxWidth(selectorId) - selector.offsetWidth));
        selector.style.width = width;
    } else {
        width = selector.offsetWidth;
    }

    /* See if position and width settings would extend beyond the
       parent element or screen. */
    var maxwidth;

    maxwidth = getXpos(dest.offsetParent) + dest.offsetParent.offsetWidth;

    if (x + width > maxwidth) {
        x = maxwidth - getBoxWidth(selectorId);
    }

    moveObject(selector, x, y);
    selector.style.visibility = 'visible';
    selectorStyle = selector.style;
}

/* Close currently opened selector. */
function closeSelector(submit)
{
    if (selectorStyle) {
        selectorStyle.visibility = 'hidden';
    }

    if (submit && !nosubmit) 
	getObject("search_form").submit();

}

var lastCountry;
        
/* Event handler for country listbox on location selector. */
function countryChanged()
{
    var country = getObject("country");

    if (lastCountry && lastCountry == country.value)
        return;

    lastCountry = country.value;

    var province = getObject("province");

    province.selectedIndex = 0;

    var len = province.length;
    for (var i = 1; i < len; i ++) {
        province.remove(1);
    }

    if (provinces[country.value] != null) { 
        for (var i = 0; i < provinces[country.value].length; i ++ ) {
            addListOption(province, provinces[country.value][i], provinces[country.value][i]);
        }
    }

    updateRange();
}

var locValues, locUnits, locCountry, locProvince, locCity;

/* Enable/disable range selector based on location selections. */
function updateRange() {
    if (locCity.value.length && (locCountry.selectedIndex > 0)) {
        locUnits.disabled = locValues.disabled = false;
    } else {
        locUnits.disabled = locValues.disabled = true;
    }
}

/* Filter out all but numeric key presses.  Used to make numeric input boxes. */
function numericsOnly(ev)
{
    var ch;

    /* How sad, this is VERY browser-specific. */
    if (ev.charCode != null) {
	ch = ev.charCode; /* Mozilla */

	if (ch == 0) {
	    /* Control keys and friends, pass through. */
	    return true;
	}
    } else {
	ch = ev.keyCode; /* IE */
    }

    /* Imagine this, hard-coded ASCII values! (in 2005) */
    if (! (ch >= 48 && ch <= 57)) {
	ev.cancelBubble = true;
	ev.returnValue = false;

	if (ev.preventDefault) {
	    ev.preventDefault(); /* Mozilla */
	}

	return false;
    }
}

/* Value setters for various criteria selectors. */
function setRuleValues() {
    var out = "";
    var linkColor;

    var form = getObject('rulesForm');

    var pets = form.pets.selectedIndex;
    var smoking = form.smoking.selectedIndex;

    if (pets > 0) {
        out += ((pets == 1) ? "allow" : "forbid") + " pets";
    }

    if (smoking > 0) {
        if (pets > 0)
            out += ", ";
        out += ((smoking == 1) ? "allow" : "forbid") + " smoking";
    }

    if (!out.length) {
        out = "any&nbsp;rules";
	linkColor = "";
    } else {
	linkColor = selectedColor;
    }

    var div = getObject('rules_div');
    div.innerHTML = out;
    div.style.color = linkColor;

    if (!nosubmit)
	getObject("search_form").submit();
}

function setRateValues() {
    var out = "";
    var linkColor;

    var form = getObject('ratesForm');

    var rate_from = form.rate_from.value;
    var rate_to = form.rate_to.value;
    var rate_cur = form.rate_cur.value;
    var rate_type = form.rate_type.options[form.rate_type.selectedIndex].text;

    if (rate_from.length && rate_to.length) {
        out += rate_from + " to " + rate_to;
    } else if (rate_from.length) {
        out += "at least " + rate_from;
    } else if (rate_to.length) {
        out += "no more than " + rate_to;
    }

    if (out.length) {
        out += " " + rate_cur + " per " + rate_type;
	linkColor = selectedColor;
    } else {
        out = "any&nbsp;amount";
	linkColor = "";
    }

    var div = getObject("rate_div");
    div.innerHTML = out;
    div.style.color = linkColor;

    if (!nosubmit)
	getObject("search_form").submit();
}

function setAccomodationValues() {
    var out = "";
    var linkColor;

    var form = getObject('accomodationsForm');

    var bedrooms_from = form.bedrooms_from.value;
    var bedrooms_to = form.bedrooms_to.value;
    var sleeps_from = form.sleeps_from.value;
    var sleeps_to = form.sleeps_to.value;

    if (bedrooms_from.length && bedrooms_to.length) {
        out += bedrooms_from + " to " + 
            bedrooms_to + " bedrooms";
    } else if (bedrooms_from.length) {
        out += "at least " + bedrooms_from + " bedrooms";
    } else if (bedrooms_to.length) {
        out += "no more than " + bedrooms_to + " bedrooms";
    }

    if ((sleeps_from.length || sleeps_to.length) &&
        (bedrooms_from.length || bedrooms_to.length)) {
        out += " and ";
    }

    if (sleeps_from.length && sleeps_to.length) {
        out += sleeps_from + " to " + 
            sleeps_to + " sleeping spaces";
    } else if (sleeps_from.length) {
        out += "at least " + sleeps_from + " sleeping spaces";
    } else if (sleeps_to.length) {
        out += "at most " + sleeps_to + " sleeping spaces";
    }

    if (!out.length) {
        out = "any&nbsp;accomodations";
	linkColor = "";
    } else {
	linkColor = selectedColor;
    }

    var link = getObject('accomodations_div');

    link.innerHTML = out;
    link.style.color = linkColor;

    if (!nosubmit)
	getObject("search_form").submit();
}

function clearSearchTerms()
{
    clearSelections('activityValues');
    setValues('activities_div', 'activityValues', 'any&nbsp;activities');
    clearSelections('amenityValues');
    setValues('amenities_div', 'amenityValues', 'any&nbsp;amenities');
    clearSelections('typeValues');
    setValues('types_div', 'typeValues', 'all&nbsp;properties');
    clearSelections('calendarsForm');
    proxyForm('calendarsForm', 'placeholder_div', function() { setCalendarValues(); });
    setCalendarValues();
    clearSelections('accomodationsForm');
    proxyForm('accomodationsForm', 'placeholder_div', function() { setAccomodationValues(); });
    clearSelections('ratesForm');
    proxyForm('ratesForm', 'placeholder_div', function() { setRateValues(); });
    clearSelections('rulesForm');
    proxyForm('rulesForm', 'placeholder_div', function() { setRuleValues(); });
    clearSelections('locationForm');
    setLocationValues('anywhere');
}

/* Clear selections in a form. */
function clearSelections(formId)
{
    var form = getObject(formId);

    for (var i = 0; i < form.elements.length; i ++) {
        var element = form.elements[i];

        if (element.type == "checkbox") {
            element.checked = false;
        } else if (element.type == "text") {
            element.value = "";
        } else if (element.type.match("^select")) {
            element.selectedIndex = 0;
        }
    }
}

/* Copies input element values from source form to dest div, replacing
   any previous values. 

   This is needed since selectors are all separate forms, mostly
   because in IE, selector divs have to be outside the search bar,
   otherwise it won't allow them to be displayed below the bar
   (everything below gets cut off since z-index for iframes gets
   ignored).  So, we "proxy" the elements, by copying them into the
   search bar form.
*/
function proxyForm(sourceFormId, destDivId, func) 
{
    var source = getObject(sourceFormId);
    var dest = getObject(destDivId);

    /* Take all the elements from the source form, place them in a
       <div>, and place that into our destination <div>. This allows
       us to easily remove all elements in order to replace them. */

    /* If our <div> already exists, remove it first. */
    var container = getObject(sourceFormId + "_placeholder");

    if (container) {
	dest.removeChild(container);
    }

    container = document.createElement("div");
    container.id = sourceFormId + "_placeholder";

    for (var i = 0; i < source.elements.length; i ++) {
        var selem = source.elements[i];

        if (selem.type == "button")
            continue;

        var elem = document.createElement("input");

        if (selem.name.length)
            elem.name = selem.name;
        else
            elem.name = selem.id;

	elem.value = selem.value;
	elem.type = "hidden";

	if (isIE) { /* ARGH. */
	    elem = document.createElement
		("<input type='" + elem.type + 
		 "' name='" + elem.name + "' value='" 
		 + elem.value + "'>");
	}
        container.appendChild(elem);
    }

    if (isIE) {
	dest.innerHTML += container.outerHTML;
    } else {
	/* Weird errors in IE. */
	dest.appendChild(container);
    }

    if (func) 
        func();

    closeSelector(0);
}

/* Display selected values for tabular selectors (activities,
   amenities, etc). */
function setValues(divName, formName, defaultText)
{
    var all = document.forms[formName].elements;
    var placeholder = getObject(divName + '_placeholder');

    var text = "";
    var linkColor;

    while (placeholder.childNodes.length) {
	placeholder.removeChild(placeholder.childNodes[0]);
    }

    for (i = 0; i < all.length; i ++) {
        if (all[i].checked) {
            var elem = document.createElement('input');

            elem.type = 'hidden';
            elem.name = all[i].name;
            elem.value = all[i].value;

            placeholder.appendChild(elem);

            if (text.length > 0) {
                text = text + ", " + all[i].title;
            } else {
                text = all[i].title;
            }
        }
    }

    if (text.length >  30) {
        text = text.substr(0, 30);
        text = text.substr(0, text.lastIndexOf(','));
        text = text + "...";
    }

    var pDiv = getObject(divName);
    if (text.length) {
        pDiv.innerHTML = text;
	pDiv.style.color = selectedColor;
    } else {
        pDiv.innerHTML = defaultText;
	pDiv.style.color = "";
    }

    closeSelector(1);
}

/* Value setter for location criteria. */
function setLocationValues()
{
    var location = "";
    setLocation(getObject("country").value, 
                getObject("province").value, 
                getObject("city").value, 
		false, false);
    closeSelector(1);
}

/* Value setter for location criteria. */
function setLocation(country, province, city, reset_distance, submit)
{
    city = capitalize(city);

    var form = getObject("locationForm");

    /* THIS SUCKS. */
    for (var i = 0; i < form.country.options.length; i ++) {
        if (form.country.options[i].value == country) {
            form.country.selectedIndex = i;
            break;
        }
    }

    /* Can't call countryChanged() directly for whatever reason, must
       be a window hierarchy issue. */
    form.country.onchange();

    /* THIS SUCKS TOO. */
    for (var i = 0; i < form.province.options.length; i ++) {
        if (form.province.options[i].value == province) {
            form.province.selectedIndex = i;
            break;
        }
    }

    form.city.value = city;

    form.province.onchange(); /* Sync range selector */

    var distance = form.range;
    var distanceUnits = form.range_units;

    if (reset_distance) {
	distance.selectedIndex = 0;
    }

    var location = "";
    var prefix;

    if (city && distance.selectedIndex > 0) {
        prefix = "within " + 
            distance.options[distance.selectedIndex].text;
        prefix += " " + 
            distanceUnits.options[distanceUnits.selectedIndex].value +
            " of ";
    }
    else
        prefix = "in ";

    if (city && city.length) {
        location += city + ", ";
    }
    if (province && province.length) {
        location += province + ", ";
    }
    if (country && country.length) {
        location += country + ", ";
    }

    if (!submit) {
	if (location && location.length) {
	    location = prefix + location.substr(0, location.length - 2);
	    getObject("location_div").innerHTML = location;
	    getObject("location_div").style.color = selectedColor;
	} else {
	    getObject("location_div").innerHTML = "anywhere";
	    getObject("location_div").style.color = "";
	}
    }

    proxyForm("locationForm", "placeholder_div");

    if (submit) {
	window.parent.redirectSearch();
    }
}

function setPageNumber(pageno) 
{
    getObject("pagenumber").value = pageno;
    getObject("search_form").submit();
}

/* Calendar value setter. */
function setCalendarValues()
{
    var out = "";

    var day_from = getListSelection('date_from_day');
    var month_from = getListSelection('date_from_month');
    var year_from = getListSelection('date_from_year');

    var day_to = getListSelection('date_to_day');
    var month_to = getListSelection('date_to_month');
    var year_to = getListSelection('date_to_year');

    if (day_from && day_from.length && day_from != "Any" && day_to != "Any") {
	out = "from " + months[month_from] + " " + 
	    day_from + ", " + year_from;
	out += " to " + months[month_to] + " " + 
	    day_to + ", " + year_to;
    }
    
    var pDiv = getObject("dates_div");

    if (out.length) {
	pDiv.innerHTML = out;
	pDiv.style.color = selectedColor;
    } else {
	pDiv.innerHTML = "on&nbsp;any&nbsp;dates";
	pDiv.style.color = "";
    }

    closeSelector(1);
}

/* Update debug query link hrefs based on selected source. */
function setDebugQueryLocations()
{
    var links = document.links;

    for (var i = 0; i < links.length; i ++) {
        links[i].href = links[i].href.substr
            (0, links[i].href.indexOf('&source='));
        links[i].href = links[i].href + '&source=' 
            + document.getElementById('source').value;
    }
}

function setListItem(list, item) {
    for (var i = 0; i < list.options.length; i++) {
	if (list.options[i].value == item) {
	    list.selectedIndex = i;
	    return;
	}
    }
}

/* Synchronize dynamic stuff with page state. */
function syncState()
{
    getObject("pagenumber").value = 1;
}

function loadFrameURL(frameId, url)
{
    var results = getObject(frameId);

    if (!results) {
	return;
    }
    
    var doc;

    if (results.contentWindow)
	doc = results.contentWindow.document;
    else if (results.document)
	doc = results.document;

    if (doc) {
	doc.location.replace(url);
    }
}


function syncSearchBox(url)
{
    if (url.indexOf('?') == -1) {
	showSearchBox();
	return;
    }

    var values = url.substring(url.indexOf('?') + 1).split('&');
    var options = new Array();

    var activities, amenities, types;
    var rules, rates, accomodations;

    clearSelections('activityValues');

    activities = getObject('activityValues').elements;
    amenities = getObject('amenityValues').elements;
    types = getObject('typeValues').elements;
    rules = getObject('rulesForm').elements;
    rates = getObject('ratesForm').elements;
    accomodations = getObject('accomodationsForm').elements;

    for (var i = 0; i < values.length; i ++) {
	var pair = values[i].split('=');

	if (pair[0].indexOf('activity_') != -1) {
	    activities[pair[0]].checked = true;
	} else if (pair[0].indexOf('amenity_') != -1) {
	    amenities[pair[0]].checked = true;
	} else if (pair[0].indexOf('type_') != -1) {
	    types[pair[0]].checked = true;
	} else {
	    options[pair[0]] = unescape(pair[1]);
	}
    }

    setLocation(options["country"], options["province"], options["city"], false, false);

    if (options["pets"]) {
	rules["pets"].selectedIndex = 2 - options["pets"];
    }
    if (options["smoking"]) {
	rules["smoking"].selectedIndex = 2 - options["smoking"];
    }

    if (options["sleeps_from"]) {
	accomodations["sleeps_from"].value = options["sleeps_from"];
    }
    if (options["sleeps_to"]) {
	accomodations["sleeps_to"].value = options["sleeps_to"];
    }
    if (options["bedrooms_from"]) {
	accomodations["bedrooms_from"].value = options["bedrooms_from"];
    }
    if (options["bedrooms_to"]) {
	accomodations["bedrooms_to"].value = options["bedrooms_to"];
    }

    if (options["rate_from"]) {
	rates["rate_from"].value = options["rate_from"];
    }
    if (options["rate_to"]) {
	rates["rate_to"].value = options["rate_to"];
    }
    if (options["rate_cur"]) {
	setListItem(rates["rate_cur"], options["rate_cur"]);
    }

    if (options["date_from_day"] && options["date_from_day"].length) {
	selectDate("date_from", 
		   options["date_from_month"], 
		   options["date_from_day"],
		   options["date_from_year"]);
	selectDate("date_to", 
		   options["date_to_month"], 
		   options["date_to_day"],
		   options["date_to_year"]);
    }

    setValues('activities_div', 'activityValues', 'any&nbsp;activities');
    setValues('amenities_div', 'amenityValues', 'any&nbsp;amenities');
    setValues('types_div', 'typeValues', 'all&nbsp;properties');
    syncCalendar("calendar_from", "date_from");
    syncCalendar("calendar_to", "date_to");

    setCalendarValues();
    proxyForm('accomodationsForm', 'placeholder_div', function() { setAccomodationValues(); });
    proxyForm('ratesForm', 'placeholder_div', function() { setRateValues(); });
    proxyForm('rulesForm', 'placeholder_div', function() { setRuleValues(); });
    proxyForm('calendarsForm', 'placeholder_div', function() { setCalendarValues(); });
    showSearchBox();
}

function showSearchBox() {
   getObject("selectorTable").style.visibility = 'visible';
}

/* Parse and redirect our iframe if necessary.  Used for main page/search page synchronization. */
function redirect_iframe(location)
{
    var urlStart = location.indexOf('?url=');

    if (urlStart == -1) {
	return;
    }

    var url = location.substring(urlStart + 5);

    syncSearchBox(url);
    loadFrameURL('results', url);
}

function redirectSearch()
{
    var url = "search?";
    var placeholders = new Array("activities_div_placeholder", "amenities_div_placeholder", 
				 "types_div_placeholder", "placeholder_div");

    var first = 1;
    for (var n = 0; n < placeholders.length; n++) {
	var p = getObject(placeholders[n]);
	for (var i = 0; i < p.childNodes.length; i ++) {
	    if (p.childNodes[i].childNodes.length > 0) {
		/* Containing div */
		for (var j = 0; j < p.childNodes[i].childNodes.length; j ++) {

		    if (p.childNodes[i].childNodes[j].value == null)
			continue;
		    if (p.childNodes[i].childNodes[j].value.length == 0)
			continue;

		    if (!first) {
			url += "&";
		    } else 
			first = 0;
		    url += escape(p.childNodes[i].childNodes[j].name);
		    url += "=" + escape(p.childNodes[i].childNodes[j].value);
		}
	    } else {
		if (p.childNodes[i].value == null)
		    continue;
		if (p.childNodes[i].value.length == 0)
		    continue;

		if (!first) {
		    url += "&";
		} else
		    first = 0;
		url += escape(p.childNodes[i].name) + "=" +
		    p.childNodes[i].value;
	    }
	}
    }
    location.href = "search.html?url=" + url;
}

/* Initialize everything.  Called on load, resize, etc. */
function init()
{
    /* We have to do the initialization here, since these are not
       defined at script load time. */
    if (locValues == null) {
        locValues = getObject('range');
        locUnits = getObject('range_units');
        locCountry = getObject('country');
        locProvince = getObject('province');
        locCity = getObject('city');
    }

    redirect_iframe(document.location.href);
    syncState();
    countryChanged();
    showAds();

    /* Safari doesn't size our results frame properly. */
    var results = getObject("results");

    if (results && results.style) {
        results.style.height = 
	    (document.body.clientHeight - 101) + 'px'; /* Sigh */
	results.style.width = 
	    (document.body.clientWidth - leftOffset) + 'px'; /* Ditto, this time for IE */
    }

    /* Turn on the horizontal scrollbar for small windows. */
    if (document.body.clientWidth < 950) {
	document.body.style.overflow = "-mozilla-scrollbars-horizontal";
    }
}

/* TODO:  Year handling sucks and should be rewritten using xxxFullYear(). */

var weekdays = new Array("S", "M", "T", "W", "T", "F", "S");

var months = new Array("January", "February", "March", "April", "May", "June", 
                       "July", "August", "September", "October", "November", 
                       "December");

var mDays = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

var dayTd = "<td class=date>";
var headTd = "<td align=center>";
var selectedDayTd = '<td class=selectedDate>';
var todayTd = '<td class=todaysDate>';

/* Return consistent year in all browsers. */
function getYear(d)
{
    return d.getFullYear();
}

function monthDays(month, year) {
    if (month != 1) {
        return mDays[month];
    } else {
        if ((year % 4) == 0 && (year % 100) != 0) {
            return 29;
        } else {
            return 28;
        }
    }
}

function populateDateControls(prefix, year) 
{
    var monthList = getObject(prefix + "_month");
    var dayList = getObject(prefix + "_day");
    var yearList = getObject(prefix + "_year");

    var now = new Date();
    var curyear = getYear(now);

    if (year == null) {
        if (yearList.selectedIndex > 0)
            year = yearList.options[yearList.selectedIndex].value;
        else
            year = curyear;
    }

    var index = monthList.selectedIndex;

    var newlen = 13;

    if (year == curyear && now.getMonth() != 0) {
        newlen = 13 - now.getMonth();
    }

    if (newlen != monthList.length) {

        while (monthList.length > 1) {
            monthList.remove(1);
        }
    
        for (var i = 0; i < months.length; i ++) {
            if ((year > curyear) || (year == curyear && now.getMonth() <= i)) {
                addListOption(monthList, months[i].substr(0, 3), i);
            }
        }
    }

    if (yearList.length < 5) {
        var now = new Date();
        var year = getYear(now);

        while (yearList.length > 1) {
            yearList.remove(1);
        }

        for (var i = year; i < year + 4; i ++) {
            addListOption(yearList, i, i);
        }
    }
}

function selectDate(prefix, month, day, year) 
{
    var monthList = getObject(prefix + "_month");
    var dayList = getObject(prefix + "_day");
    var yearList = getObject(prefix + "_year");

    var days;
    var now = new Date();
    var curyear = getYear(now);

    if (year == curyear && now.getMonth() == month) {
	days = monthDays(month, year) - now.getDate() + 2;
    } else {
	days = monthDays(month, year) + 1;
    }

    if (dayList.length != days) {
        while (dayList.length > 1) {
            dayList.remove(1);
        }
        
	if (month == now.getMonth() && year == curyear) {
	    for (var i = now.getDate(); i <= monthDays(month, year); i ++) {
		addListOption(dayList, i, i);
	    }
	} else {
	    for (var i = 1; i <= monthDays(month, year); i ++) {
		addListOption(dayList, i, i);
	    }
	}
    }
    
    if (month != null) {
        for (var i = 1; i < monthList.length; i++) {
            if (monthList.options[i].value == month) {
                monthList.selectedIndex = i;
                break;
            }
        }
    }

    if (day) {
	if (month == now.getMonth() && year == curyear) {
	    dayList.selectedIndex = day - now.getDate() + 1;
	} else {
	    dayList.selectedIndex = day;
	}
    }

    var maxyear = yearList.options[yearList.length - 1].value;

    if (year > maxyear) {
        maxyear ++; /* Very strange, maxyear + 1 in the for
                       initializer just doesn't work. */
        for (var i = maxyear; i <= year; i ++) {
            addListOption(yearList, i, i);
        }
    }

    yearList.selectedIndex = year - curyear + 1;
}

function syncCalendar(divId, prefix) {
    var monthList = getObject(prefix + "_month");
    var dayList = getObject(prefix + "_day");
    var yearList = getObject(prefix + "_year");

    var month, day, year;

    if (yearList.selectedIndex > 0) {
        year = yearList.options[yearList.selectedIndex].value;
    }
    if (monthList.selectedIndex > 0) {
        month = monthList.options[monthList.selectedIndex].value;
    } else {
        while (dayList.length > 1)
            dayList.remove(1);
    }
    if (dayList.selectedIndex > 0) {
        day = dayList.options[dayList.selectedIndex].value;
    }

    if (!isNaN(month) && !isNaN(year)) {
        showCalendar(divId, prefix, parseInt(month), parseInt(year), parseInt(day));
    }
}

function showCalendar(divId, prefix, month, year, selectedDay)
{
    var div = getObject(divId);

    var now = new Date();
    var today = null;
    var first = new Date();

    if (year == null) {
        year = getYear(first);
    } else {
        first.setFullYear(year);
    }

    if (month == null) {
        month = first.getMonth();
    } else {
        first.setMonth(month);
    }

    if (getYear(now) == year && now.getMonth() == month) {
        today = now.getDate();
    }

    first.setDate(1);

    if (prefix) {
        populateDateControls(prefix, year);
        selectDate(prefix, month, selectedDay, year);
    }

    var out;

    var startDay = first.getDay();

    out = "<table><tr>";
    
    var pmon, pyear, nmon, nyear;

    pyear = year;
    nyear = year;

    if (month > 0) {
        pmon = month - 1;
    } else {
        pmon = 11;
        pyear --;
    }

    if (month < 11) {
        nmon = month + 1;
    } else {
        nmon = 0;
        nyear ++;
    }

    out += '<td colspan=2 aligh=left>';

    if (pyear <= getYear(now) && pmon < now.getMonth()) {
        out += "&nbsp;";
    } else {
        out += '<input type=button  class=calendarNav href="#" onclick="showCalendar(\'' 
            + divId + "','" + prefix + "'," 
            + pmon + ',' + pyear + '); return false;" value="-"</input>';
    }

    out += "<td colspan=3 align=center>";

    out += months[month].substr(0, 3) + " " + year + "</td>";

    out += '<td colspan=2 align=right><input type=button class=calendarNav onclick="showCalendar(\'' 
        + divId + "','" + prefix + "'," 
        + nmon + ',' + nyear + '); return false;" value="+"</input>';
    
    out += "</td></tr><tr>";

    for (var i = 0; i < weekdays.length; i ++) {
        out += headTd + weekdays[i] + "</td>";
    }

    out += "</tr><tr>";

    for (var i = 0; i < startDay; i ++) {
        out += dayTd + "&nbsp;</td>";
    }

    var curDay = startDay;

    var rows = 0;
    var day;

    for (day = 1; day <= monthDays(month, year); day ++) {
        if (day == selectedDay) {
            out += selectedDayTd;
        } else if (day == today) {
            out += todayTd;
        } else {
            out += dayTd;
        }

        if (today == null || day >= today) {
            out += '<a href="#" onclick="showCalendar(\'' 
                + divId + "','" + prefix + "'," 
                + month + ',' + year + ',' + day + '); return false;">' + day + "</a></td>";
        } else {
            out += day + '</td>';
        }
        
        curDay ++;
        if (curDay > 6) {
            curDay = 0;
            out += "</tr><tr>";
            rows ++;
        }
    }

    for (day = 1; rows < 6; day ++) {
        out += dayTd + "&nbsp;" + "</td>";
        curDay ++;
        if (curDay > 6) {
            curDay = 0;
            out += "</tr><tr>";
            rows ++;
        }
    }

    out += "</td></tr>";

    div.innerHTML = out;
}

function getObjectsByName(tag, name, doc) {
    if (!isIE) {
	return doc.getElementsByName(name);
    }

    var elems = doc.getElementsByTagName(tag);
    var ra = new Array();

    for (var i = 0; i < elems.length; i ++) {
	if (elems[i].name == name) {
	    ra.push(elems[i]);
	}
    }

    return ra;
}

function getSpansByName(name) {
    var divs = getObjectsByName("span", name, self.document);

    if (divs.length != 0)
	return divs;

    return getObjectsByName("span", name, window.parent.document); 
}

function getDivsByName(name) {
    var divs = getObjectsByName("div", name, self.document);

    if (divs.length != 0)
	return divs;

    return getObjectsByName("div", name, window.parent.document); 
}

function adserveResponse(divId, adText) {
    getObject(divId).innerHTML = adText;
}

function getAdSize(adId) {
    var rules = getStyleRules(adId);
    var ad = getObject(adId);
    var size = "";

    if (rules && rules.width)
	size += parseInt(rules.width);
    else
	size += isIE ? ad.offsetWidth + 1 : ad.offsetWidth;

    if (rules && rules.height)
	size += parseInt(rules.height);
    else 
	size += ad.offsetHeight;

    return size;
}

function showAds() {
    var adDivs = getDivsByName("ad_div");
    var divs_list = "";

    var activities = 0;
    var activities_div = getObject("activities_div_placeholder");

    for (var i = 0; i < activities_div.childNodes.length; i ++) {
	var m = activities_div.childNodes.item(i).name.match(/\d+/);

	/* I wonder if anybody has ever done bit operations in
	 * Javascript. */
	activities |= (1 << (m[0] - 1)); 
    }

    var params = "0:" + getObject("country").value + ":" + 
	getObject("province").value + ":" + activities;

    for (var i = 0; i < adDivs.length; i ++) {
	divs_list += (":" + adDivs[i].id + "@" + getAdSize(adDivs[i].id));
    }

    getObject("ad_divs_placeholder").value = divs_list;
    params += divs_list;
    loadFrameURL('adserve_frame', "ZVadserve?params=" + params);
}

function showRefineBox()
{
    var div = getObject("refine_div");

    div.innerHTML = "The search box on top of the page can be used at any time to refine your criteria.";
}

function redirectCountry(country) {
    location.href = "search.html?url=search?country=" + escape(country);
}

function unhideEmails()
{
  var spans = getSpansByName("email");

  for (var i = 0; i < spans.length; i ++) {
    spans[i].innerHTML = spans[i].innerHTML.replace(/%20%5Bat%5D%20/g, '@');
    spans[i].innerHTML = spans[i].innerHTML.replace(/ \[at\] /g, '@');
  }
}

function framepage() {
  if (top.location.href.indexOf("search.html") == -1) {
    top.location.href = "/search.html?url=" + location.pathname;
  }
}
