﻿/// <reference path="scripts/prototype.js" />
if (!AroReserve) var AroReserve = {};
//===========================================================================
AroReserve.Utils = {
    fillZero: function(num, len)
    {
        str = num.toString();
        for (i = 0; i < len - str.length; i++)
            str = '0' + str;
        return str;
    },

    setClass: function(el, className, status)
    {
        if (status)
        {
            el.addClassName(className);
        }
        else
        {
            el.removeClassName(className);
        }
    },

    setSelectOption: function(select, value)
    {
        for (var i = 0; i < select.options.length; i++)
            if (select.options[i].value == value)
        {
            select.options[i].selected = true;
            break;
        }
    },

    dateDiff: function(date1, date2)
    {
        return Math.ceil((date2 - date1) / (3600 * 24 * 1000));
    }
};
//===========================================================================
AroReserve.AvailabilityPanel = Class.create();
AroReserve.AvailabilityPanel.prototype =
{
    offerID: null,
    panel: null,
    panelLoading: null,
    panels: new Array(),
    rooms: new Array(),
    cells: new Array(),
    dates: {},

    startDate: null,
    minStay: 1,
    maxStay: 99,
    checkinLimits: null,
    draggingEnabled: true,

    dragging: false,
    predragging: false,
    dragStartCell: null,
    checkinLimitsText: null,

    windowDays: 0,
    selectedDate: null,
    selectedNights: 1,
    selectedCell: null,
    checkinDate: null,
    reloading: false,

    nightsControl: null,
    checkinDayControl: null,
    checkinMonthControl: null,
    buttonControl: null,

    initialize: function(config)
    {
        if (config)
        {
            if (config.startDate) this.startDate = config.startDate;
            if (config.minStay) this.minStay = config.minStay;
            if (config.maxStay) this.maxStay = config.maxStay;
            if (config.selectedNights) this.selectedNights = config.selectedNights;
            if (config.checkinLimits) this.checkinLimits = config.checkinLimits;
        }

        this.panels.push(this);
        if (!this.startDate) this.startDate = new Date();

        if (this.checkinLimits)
        {
            this.checkinLimitsText = '';
            for (var i = 0; i < this.checkinLimits.length; i++)
            {
                var day = this.checkinLimits[i];
                if (AroReserve.Localized.weekdayNames[day])
                    this.checkinLimitsText += (this.checkinLimitsText ? ', ' : '') + AroReserve.Localized.weekdayNames[day];
            }
        }

        document.ondragstart = function() { return false; };
        document.onselectstart = function() { return false; };

    },

    registerNights: function(id)
    {
        //console.log('registerNights(' + id + ')');
        this.nightsControl = $(id);
        this.selectedNights = parseInt($F(id));
        Event.observe(this.nightsControl, 'change', this.onNightsChanged.bind(this));
    },

    registerCheckin: function(monthid, dayid)
    {
        //console.log('registerCheckin(' + monthid + ',' + dayid + ')');
        this.checkinDayControl = $(dayid);
        if (this.checkinDayControl)
        {
            Event.observe(this.checkinDayControl, 'change', this.onCheckinChanged.bind(this));
        }

        this.checkinMonthControl = $(monthid);
        if (this.checkinMonthControl)
        {
            Event.observe(this.checkinMonthControl, 'change', this.onCheckinChanged.bind(this));
        }
    },

    registerButton: function(id)
    {
        this.buttonControl = $(id);
        this.updateButton(false);
    },

    registerSORefresher: function(id)
    {
        this.SORefresher = $(id);
    },

    registerPanel: function(id)
    {
        this.reloading = false;
        //console.log('registerPanel(' + id + ')');
        this.panel = $(id);
        if (!this.panel)
        {
            //console.log(id + ' missing');
            return;
        }
        var datePicker = this.panel.down('.datePicker');
        if (datePicker)
        {
            datePicker.panel = this;
        }
        this.panelLoading = this.panel.next('.panelLoading');
        this.rooms = this.panel.select('.roomRow');
        this.cells = new Array();
        for (var i = 0; i < this.rooms.length; i++)
        {
            var room = this.rooms[i];
            room.index = i;
            this.cells[i] = room.select('.priceDay');
            this.windowDays = Math.max(this.windowDays, this.cells[i].length);
            for (var j = 0; j < this.cells[i].length; j++)
            {
                var date = new Date(this.startDate.getFullYear(), this.startDate.getMonth(), this.startDate.getDate() + j);
                var cell = this.cells[i][j];
                cell.date = date;
                cell.room = room;
                cell.roomIndex = room.index;
                cell.index = j;
                cell.tooltip = cell.down('.tooltip');
                if (cell.tooltip) cell.tooltip.template = cell.tooltip.innerHTML;
                Event.observe(cell, 'mouseenter', this.onMouseEnter.bind(this, cell));
                Event.observe(cell, 'mouseleave', this.onMouseLeave.bind(this, cell));
                Event.observe(cell, 'click', this.onClick.bind(this, cell));
                Event.observe(cell, 'mouseup', this.onMouseUp.bind(this, cell));
                Event.observe(cell, 'mousedown', this.onMouseDown.bindAsEventListener(this, cell));
                //cell.onmousedown = this.onMouseDown;
            }

            room.roomsNumber = room.down('select');
            if (room.roomsNumber)
            {
                room.roomsNumber.roomIndex = room.index;
                Event.observe(room.roomsNumber, 'change', this.onRoomsChanged.bindAsEventListener(this, i));
            }
        }

        var $this = this;
        this.panel.select('.causesLoading').each(function(el)
        {
            if (el.href) Event.observe(el, 'click', $this.loading.bind($this));
        });
    },

    registerTrigger: function(id)
    {
        var trigger = $(id);
        if (trigger)
        {
            Event.observe(trigger, 'change', this.onTrigger.bind(this));
        }
    },

    selectCell: function(cell, length)
    {
        if (cell == null)
        {
            this.selectedNights = length;
            return;
        }
        if (cell.date) this.selectedDate = cell.date;
        // verify stay length is in valid range
        if (length < this.minStay) length = this.minStay;
        if (length > this.maxStay) length = this.maxStay;
        this.highlightSel(cell, length);
        this.updateNights(length);
        this.updateDate();
        this.updateRooms(true);
    },

    resetDate: function()
    {
    },

    updateNights: function(nights)
    {
        this.selectedNights = nights;
        if (this.nightsControl)
        {
            AroReserve.Utils.setSelectOption(this.nightsControl, nights);
        }
    },

    updateRooms: function(status)
    {
        //console.log('updateRooms(' + status + ')');
        var exceptRoom = null
        if (this.selectedCell)
        {
            // save selected room index and increment rooms number
            exceptRoom = this.selectedCell.roomIndex;
            this.rooms[exceptRoom].roomsNumber.selectedIndex = 1;
        }
        // reset all room numbers to 0 except selected one
        this.panel.select('SELECT').each(function(c)
        {
            if (c.roomIndex != exceptRoom)
                c.selectedIndex = 0;
        });
        this.updateButton(this.checkAnyRoomSelected());
    },

    updateDate: function()
    {
        if (!this.checkinDayControl || !this.checkinMonthControl) return;
        if (this.selectedDate)
        {
            var selMonth = this.selectedDate.getFullYear() + '-' + AroReserve.Utils.fillZero(this.selectedDate.getMonth() + 1, 2);
            var selDay = this.selectedDate.getDate();

            AroReserve.Utils.setSelectOption(this.checkinDayControl, selDay);
            AroReserve.Utils.setSelectOption(this.checkinMonthControl, selMonth);
        }
        this.checkDiff(this.selectedDate);
    },

    updateButton: function(status)
    {
        //console.log('updateButton(' + status + ')');
        if (!this.buttonControl) return;

        if (status)
        {
            this.buttonControl.removeClassName('inactive');
        }
        else
        {
            this.buttonControl.addClassName('inactive');
        }
        this.buttonControl.disabled = !status;
    },

    checkAvailable: function(cell, length)
    {
        var row = this.cells[cell.roomIndex];
        for (var i = cell.index; i < Math.min(row.length, cell.index + length); i++)
        {
            if (row[i].down('div').hasClassName('unavail'))
                return false;
        }
        return true;
    },

    checkAnyRoomSelected: function()
    {
        var selected = 0;
        this.panel.select('SELECT').each(function(c)
        {
            selected += c.selectedIndex;
        });
        return selected > 0;
    },

    checkPast: function(date)
    {
        var today = new Date();
        if (date)
        {
            var diff = AroReserve.Utils.dateDiff(today, date);
            if (diff < 0)
            {
                this.selectedDate = today;
                this.updateDate();
                return false;
            }
        }
        else
            this.resetDate();
        return true;
    },

    checkDiff: function(date)
    {
        var diff = AroReserve.Utils.dateDiff(this.startDate, date);
        if (diff == 0) return true;
        if (diff < 0 || diff > this.windowDays - this.selectedNights)
        {
            this.loading();
            this.reload();
            return false;
        }
        return true;
    },

    checkLimit: function(date, alert)
    {
        if (date)
        {
            if (this.checkinLimits && this.checkinLimits.indexOf(date.getDay().toString(), 0) == -1)
            {
                if (alert) alert(AroReserve.Localized.msg_CheckinLimits);
                return false;
            }
        }
        return true;
    },

    highlight: function(cell, next, className, status)
    {
        //console.log('highlight ' + cell.index + ',' + next + ',' + className + ',' + status);
        if (!this.checkAvailable(cell, next))
        {
            cell.style.cursor = 'not-allowed';
            cell.title = AroReserve.Localized.msg_CannotCheckin;
            return false;
        }
        if (!this.checkLimit(cell.date, false))
        {
            cell.style.cursor = 'not-allowed';
            cell.title = AroReserve.Localized.msg_CheckinLimits.replace('{0}', AroReserve.Localized.msg_CheckinLimits_Days);
            return false;
        }
        cell.style.cursor = '';
        cell.title = '';
        var row = this.cells[cell.roomIndex];
        for (var i = cell.index; i < Math.min(row.length, cell.index + next); i++)
        {
            if (i == cell.index)
                AroReserve.Utils.setClass(row[i], (next == 1) ? (className + 'StartEnd') : (className + 'Start'), status);
            else
                AroReserve.Utils.setClass(row[i], (i == cell.index + next - 1) ? (className + 'End') : (className + 'Mid'), status);
        }
        return true;
    },

    unHighlight: function()
    {
        //console.log('unHighlight()');
        for (var i = 0; i < this.cells.length; i++)
        {
            for (var j = 0; j < this.cells[i].length; j++)
            {
                this.cells[i][j].removeClassName('selectStartEnd');
                this.cells[i][j].removeClassName('selectStart');
                this.cells[i][j].removeClassName('selectEnd');
                this.cells[i][j].removeClassName('selectMid');
            }
        }
        this.updateButton(false);
    },

    highlightCol: function(cell, next, className, status)
    {
        for (var i = 0; i < this.cells.length; i++)
        {
            for (var j = cell.index; j < Math.min(this.cells[i].length, cell.index + next); j++)
            {
                AroReserve.Utils.setClass(this.cells[i][j], className, status);
            }
        }
        return true;
    },

    highlightSel: function(cell, length)
    {
        if (this.selectedCell)
        {
            this.unHighlight();
            this.highlightCol(this.selectedCell, this.selectedNights, 'range', false);
            //TODO updateNum(false);
        }
        this.selectedCell = cell;
        this.selectedNights = length;
        if (cell)
        {
            if (!this.highlight(cell, length, 'select', true))
            {
                this.selectedCell = null;
            }
            else
            {
                this.highlightCol(cell, length, 'range', true);
            }
        }
    },

    reload: function(src)
    {
        if (this.reloading) return;
        if (!src) src = this.checkinMonthControl ? this.checkinMonthControl.id : '';
        cmd = '__doPostBack(\'' + src + '\',\'SCROLL\')';
        this.reloading = true;
        setTimeout(cmd, 0);
    },

    loading: function()
    {
        //console.log('loading()');
        if (this.panelLoading) this.panelLoading.style.height = this.panel.getHeight() + 'px';
        this.panel.hide();
        if (this.panelLoading) this.panelLoading.show();
    },

    loaded: function()
    {
        console.log('loaded()');
        this.reloading = false;
    },

    getCell: function(e)
    {
        return Event.element(e).up('.priceDay');
    },

    onMouseDown: function(e, cell)
    {
        //console.log("onMouseDown");
        //TODO if (this.minStay == this.maxStay) return false;
        if (this.draggingEnabled)
        {
            this.predragging = true;
            this.dragStartCell = cell;
        }
        Event.stop(e);
    },

    onMouseUp: function(cell)
    {
        //console.log("onMouseUp");
        if (this.dragging)
        {
            this.highlight(this.dragStartCell, cell.index - this.dragStartCell.index + 1, 'high', false);
            this.selectCell(this.dragStartCell, cell.index - this.dragStartCell.index + 1);
        }
        this.dragStartCell = null;
        this.predragging = false;
        this.dragging = false;
    },

    onClick: function(cell)
    {
        this.dragStartCell = null;
        this.predragging = false;
        this.dragging = false;
        this.selectCell(cell, this.selectedNights);
    },

    onMouseEnter: function(cell)
    {
        //console.log("onMouseEnter cell[" + cell.index + "," + cell.roomIndex + "] from " + this.panel.id);
        if (this.dragging)
            this.highlight(this.dragStartCell, cell.index - this.dragStartCell.index + 1, 'high', true);
        else
            this.highlight(cell, this.selectedNights, 'high', true);

        if (cell.tooltip)
        {
            cell.tooltip.innerHTML = cell.tooltip.template.replace('{0}', this.selectedNights);
            cell.tooltip.style.display = 'block';
        }
    },

    onMouseLeave: function(cell)
    {
        //console.log("onMouseLeave");
        if (this.predragging)
        {
            this.dragging = true;
            this.predragging = false;
        }
        if (this.dragging)
            this.highlight(this.dragStartCell, cell.index - this.dragStartCell.index + 1, 'high', false);
        else
            this.highlight(cell, this.selectedNights, 'high', false);

        if (cell.tooltip) cell.tooltip.style.display = 'none';
    },

    onNightsChanged: function()
    {
        //console.log('onNightsChanged');
        this.selectCell(this.selectedCell, parseInt($F(this.nightsControl)));
        if (this.SORefresher && this.SORefresher.click)
        {
            this.SORefresher.click();
        }
    },

    onCheckinChanged: function()
    {
        var strDate = $F(this.checkinMonthControl) + '-' + AroReserve.Utils.fillZero($F(this.checkinDayControl), 2);
        var date = new Date(strDate.replace(/-/g, '/'));

        if (this.checkPast(date) && this.checkDiff(date) && this.checkLimit(date, true))
        {
            if (this.selectedCell)
            {

                var row = this.cells[this.selectedCell.roomIndex];
                var cell = null;
                for (var i = 0; i < row.length; i++)
                {
                    if (row[i].date.getTime() == date.getTime())
                        cell = row[i];
                }
                if (cell)
                    this.selectCell(cell, this.selectedNights);
            }
        }
    },

    onRoomsChanged: function(e, roomIndex)
    {
        var roomsNumber = this.rooms[roomIndex].roomsNumber;
        var num = parseInt($F(roomsNumber));
        var startCell = null;
        if (this.selectedCell)
        {
            if (!this.highlight(this.cells[roomIndex][this.selectedCell.index], this.selectedNights, 'select', num > 0))
            {
                roomsNumber.selectedIndex = 0;
                this.updateButton(this.checkAnyRoomSelected());
                Event.stop(e);
                return false;
            }
        }
        else
        {
            this.selectCell(this.cells[roomIndex][0], this.selectedNights);
        }
        this.updateButton(this.checkAnyRoomSelected());
    },

    onTrigger: function(e)
    {
        var el = Event.element(e);
        this.loading();
        this.reload(el.id);
    }
};
//===========================================================================
AroReserve.SOPanelsManager = Class.create();
AroReserve.SOPanelsManager.prototype = Object.extend(new AroReserve.AvailabilityPanel(),
{
    registerPanel: function(id)
    {
        this.reloading = false;
        this.panel = $(id);
        if (!this.panel) return;
        this.panelLoading = this.panel.next('.panelLoading');
    },

    onCheckinChanged: function()
    {
        //console.log('SOPanelsManager.onCheckinChanged()');
        this.loading();
        this.reload();
    }
});
//===========================================================================
AroReserve.SOAvailabilityPanel = Class.create();
AroReserve.SOAvailabilityPanel.prototype = Object.extend(new AroReserve.AvailabilityPanel(),
{
    onDateChanged: function()
    {
        //console.log('SOAvailabilityPanel.onDateChanged()');
        if (AroReserve.MainPanel != null)
        {
            if (AroReserve.MainPanel)
            {
                this.loading();
                AroReserve.MainPanel.loading();
                AroReserve.MainPanel.reload();
            }
        }
    }
});
//===========================================================================
AroReserve.Popup = {
    Popups: new Array(),

    Register: function(openid, popid)
    {
        var popup = $(popid);
        if (!popup) return;
        this.Popups.push(popid);
        Event.observe(document, 'dom:loaded', this.Close.bind(this, popid));
        Event.observe($(openid), 'click', this.Open.bind(this, popid));
        //Event.observe($(openid), 'mouseenter', this.Open.bind(this, popid, null));
        //Event.observe($(openid), 'mouseleave', this.Close.bind(this, popid, null));
        Event.observe(popup, 'click', this.Close.bind(this, popid));
        var $this = this;
        popup.select('.closePopup').each(function(el)
        {
            Event.observe(el, 'click', $this.Close.bind($this, popid));
        });
    },

    Open: function(id, e)
    {
        this.Popups.each(function(id)
        {
            var popup = $(id);
            if (popup) popup.hide();
        });
        $(id).show();
        if (e) Event.stop(e);
    },

    Close: function(id, e)
    {
        $(id).hide();
        if (e) Event.stop(e);
    }
};
//===========================================================================
AroReserve.Expander = {
    Register: function(linkid, sectionid, headerid)
    {
        Event.observe($(linkid), 'click', this.Toggle.bindAsEventListener(this, sectionid, headerid));
    },

    Toggle: function(e, sectionid, headerid)
    {
        if (sectionid)
        {
            var section = $(sectionid);
            if (section)
            {
                section.toggle();
                section.toggleClassName('active');
            }
        }
        if (headerid)
        {
            var header = $(headerid);
            if (header)
            {
                header.toggleClassName('active');
            }
        }
        if (e) Event.stop(e);
    },

    Expand: function(e, sectionid, headerid)
    {
        if (sectionid)
        {
            var section = $(sectionid);
            if (section)
            {
                section.show();
                section.addClassName('active');
            }
        }
        if (headerid)
        {
            var header = $(headerid);
            if (header)
            {
                header.addClassName('active');
            }
        }
        if (e) Event.stop(e);
    }
};
