﻿/**
The AJAX-based search box class.

Required: jQuery 1.2.6
*/
function BookingStudio_SearchBox(formId)
{
    var that = this;
    
    this._appPath = arguments.length == 2 ? arguments[1] : "";    
    
    /* Public params */
    this.defaultLoadParams = {};

    /* Public data provider callbacks */
    this.onAddMonthYear = null;
    this.onAddDuration = null;
    this.onAddAdult = null;
    this.onAddChild = null;
    this.onAddInfant = null;
    this.onAddPet = null;
    this.onAddLocation = null;
    this.onAddFacility = null;
    this.onAddPrice = null;
    this.onDataLoaded = null;
    
    /* Public data validation callbacks */
    this.onValidate = null;
    this.onShowErrors = null;
    
    /* Form elements */
    this._formId = formId;
    this._date = null;
    this._monthYear = null;
    this._duration = null;
    this._adults = null;
    this._children = null;
    this._infants = null;
    this._pets = null;
    this._location = null;
    this._price = null;
    this._facilities = [];
    
    /* Find known form elements */
    var form = $("#" + this._formId);
    if (form) {
        form.submit(function() {
            if (typeof(that.onValidate)=="function") {
                var errors = that.onValidate({
                    date: that._date,
                    monthYear: that._monthYear,
                    duration: that._duration,
                    adults: that._adults,
                    children: that._children,
                    infants: that._infants,
                    pets: that._pets,
                    location: that._location,
                    price: that._price,
                    facilities: that._facilities
                });
                if (errors) {
                    if (typeof(that.onShowErrors)=="function") {
                        that.onShowErrors(errors);
                    } else {
                        var msg = "";
                        $.each(errors, function(i, err) { msg += err + "\n"; });
                        alert(msg);
                    }
                    return false;
                }
                return true;
            }
        });
        for (var i = 0; i < form.get(0).elements.length; i++) {
            var elem = form.get(0).elements[i];
            switch (elem.name) {
            case "DAT": this._date = jQuery(elem); break;
            case "MONTHYEAR": this._monthYear = jQuery(elem); break;
            case "DUR": this._duration = jQuery(elem); break;
            case "ADU": this._adults = jQuery(elem); break;
            case "CHI": this._children = jQuery(elem); break;
            case "INF": this._infants = jQuery(elem); break;
            case "PET": this._pets = jQuery(elem); break;
            case "LOC": this._location = jQuery(elem); break;
            case "AMT": this._price = jQuery(elem); break;
            default:
                if (/^FAC\d+$/.test(elem.name)) {
                    var id = parseInt(elem.name.substr(3));
                    this._facilities.push({ id: id, elem: jQuery(elem), group: null });
                }
            }
        }
    } else {
        alert("SearchBox form not found!");
    }
    
    /* Setup handler for dates */
    if (this._monthYear) {
        this._monthYear.change(function() {
            that.updateDates();
        });
    }
    
    this.addBooleanFacilities = function(groupId, facilities) {
        for (var i = 0; i < facilities.length; i++) {
            this._facilities.push({ id: facilities[i], elem: null, group: groupId});
        }
    }
    
    this.loadData = function() {
        var test = arguments.length == 1 ? arguments[0] : false;
        if (test) {
            that._updateForm(test);
        } else {
            var url = that._dataUrl() + that._getDefaultLoadParams(window.location.search);
            $.getJSON(url + (url.indexOf("?") > -1 ? "&" : "?") + "cc=" + (new Date()).valueOf().toString(), that._updateForm);
        };
    }
    
    this._getDefaultLoadParams = function(querystring) {
        var result = "";
        for (var key in that.defaultLoadParams) {
            if (querystring.indexOf(key + "=") == -1) {
		if (result.length > 0) {
			result += "&";
		}
                result += key + "=" + encodeURI(that.defaultLoadParams[key]);
            }
        }
	result = querystring.length == 0 ? "?" + result : querystring + result;
	return result;
    }
    
    this._updateForm = function(data) {
        data.selectedDate = that._convertDate(data.selectedDate);
        var fields = [
            { member: that._monthYear, callback: that.onAddMonthYear, data: "dates" },
            { member: that._duration, callback: that.onAddDuration, data: "durations" },
            { member: that._adults, callback: that.onAddAdult, data: "adults" },
            { member: that._children, callback: that.onAddChild, data: "children" },
            { member: that._infants, callback: that.onAddInfant, data: "infants" },
            { member: that._pets, callback: that.onAddPet, data: "pets" },
            { member: that._location, callback: that.onAddLocation, data: "locations" },
            { member: that._price, callback: that.onAddPrice, data: "prices" }
        ];
        $.each(fields, function(i, field) {
            if (field.member) {
                var items = data[field.data];
                $.each(items, function(i,item) {
                    if (item) {
                        if (typeof(field.callback)=="function") {
                            field.callback(item, i);
                        } else {
                            that._addOption(field.member.get(0), item);
                        }
                    }
                });
            }
        });
        that.updateDates();
        that.setSelectedDate(data.selectedDate);
        $.each(that._facilities, function(i, facility) {
            if (facility && facility.id) {
                var dataFacility = null;                
                $.each(data.facilities, function(j, df) { if (facility.id == df.id) dataFacility = df; });
                if (dataFacility) {
                    if (facility.elem && dataFacility.options && dataFacility.options.length > 0) {
                        if (typeof(that.onAddFacility)=="function") {
                            that.onAddFacility(facility, dataFacility);
                        } else {
                            that._fill(facility.elem.get(0), dataFacility.options);
                        }
                    } else {
                        facility.elem = $("#" + facility.group);
                        if (typeof(that.onAddFacility)=="function") {
                            that.onAddFacility(facility, dataFacility);
                        } else {
                            facility.elem.append(that._makeCheckbox(facility, dataFacility));
                        }                            
                    }
                };
            }
        });
        if (typeof(that.onDataLoaded)=="function") {
            that.onDataLoaded();
        }
    }
    
    this.setSelectedDate = function(date) {
        if (typeof(date) == "object") {
            date = that._formatDate(date);
        }
        var monthYearDate = date.substr(0, "yyyy-MM-".length) + "01";
        if (that._monthYear.val() != monthYearDate) {
            that._monthYear.val(monthYearDate);
            that.updateDates();
        }
        that._date.val(date);

    }
    
    this.updateDates = function() {
        var days = ["sun","mon","tue","wed","thu","fri","sat"];
        var monthYearDate = that._convertDate(that._monthYear.val());
	    var month = monthYearDate != null ? monthYearDate.getMonth() : (new Date()).getMonth();
	    var year = monthYearDate != null ? monthYearDate.getFullYear() : (new Date()).getFullYear();
	    var date = new Date(year, month, 1);
	    if (date < new Date()) {
	        month = (new Date()).getMonth();
	        year  = (new Date()).getFullYear();
	        date  = new Date(year, month, (new Date()).getDate());
	    }
	    var selectedDay = 1;
	    if (/^\d\d\d\d-\d\d-\d\d$/.test(that._date.val())) {
            selectedDay = parseInt(that._date.val().substr("yyyy-MM-".length, 2).replace(/^0*/, ""));
        } else {
            selectedDay = parseInt(that._formatDate(new Date()).substr("yyyy-MM-".length, 2).replace(/^0*/, ""));
        }
        if (selectedDay < date.getDate()) {
            selectedDay = date.getDate();
        }
	    var select = that._date.get(0);
	    that._empty(select);
	    while (date.getMonth() == month) {
		    var option = new Option(date.getDate().toString(), that._formatDate(date));
		    option.className = days[date.getDay()];
		    select.options[select.options.length] = option;
		    date = new Date(date.getFullYear(), date.getMonth(), date.getDate()+1 );
	    }
	    that.setSelectedDate(new Date(year, month, selectedDay));
    }
    
    this._substr = function(str, start) {
        if (!str) return "";
        var length = (arguments.length == 3) ? arguments[2] : null;
        if (length) return str.substr(start, length);
        return str.substr(start);
    }
    
    this._formatDate = function(date) {
        return date.getFullYear() + "-" + that._right("0" + (date.getMonth() + 1).toString(), 2) + "-" + that._right("0" + date.getDate(), 2);
    }
    
    this._dataUrl = function() {
        var url = "";
        if (window.location.protocol && window.location.host) {
            url = window.location.protocol + "//" + window.location.host;
        } else {
            var index = window.location.href.indexOf("/", "http://".length);
            if (index > -1) {
                url = window.location.href.substr(0, index);
            } else {
                url =window.location.href;
            }
        }
        return url + that._appPath + "/Search/Box";
    }
    
    this._right = function(str, length) {
        return str.substr(str.length - length);
    }
    
    this._fill = function(select, options) {
        $.each(options, function(i, option) { that._addOption(select, option); });
    }
    
    this._addOption = function(select, option) {
        if (select && option) {
            if (option.value) {
                select.options[select.options.length] = new Option(option.text, option.value);
            } else {
                select.options[select.options.length] = new Option(option.text);
            }
            if (option.selected) {
                select.options[select.options.length - 1].selected = option.selected;
            }
        }
    }
    
    this._empty = function(select) {    
        while (select.options.length > 0) select.options[0] = null;
    }
    
    this._makeCheckbox = function(facility, data) {
        var scopedId = that._formId + "_FAC" + facility.id;
        return "<li>" + 
                   "<input type=\"checkbox\" name=\"FAC" + facility.id + "\" id=\"" + scopedId + "\" value=\"" + data.value + "\"" + (data.selected ? " checked=\"checked\"" : "") + " />" +
                   "&nbsp;" +
                   "<label for=\"" + scopedId + "\">" + data.text + "</label>" +
               "</li>";                        
    }
    
    this._convertDate = function(strDate) {
        if (/^(\d\d\d\d)-(\d\d)-(\d\d)$/.test(strDate)) {
            var year = parseInt(strDate.substr(0, 4));
            var month = parseInt(strDate.substr("yyyy-".length, 2).replace(/^0/, "")) - 1; // JS months start at 0
            var day = parseInt(strDate.substr("yyyy-MM-".length, 2).replace(/^0/, ""));
            if (year != "NaN" && month != "NaN" && day != "NaN") {
                return new Date(year, month, day);
            }
        }
        return null;
    }
}
