﻿///<reference path="../TESCO.js" />
///<reference path="../event.js" />
///<reference path="../eventManager.js" />
///<reference path="../exception.js" />
///<reference path="../node.js" />
///<reference path="../position.js" />
///<reference path="../effects.js" />
///<reference path="../XMLHTTP.js" />
///<reference path="../ajax.js" />

TESCO.UI.DeliverySlots = (function() {

    //#region
    //  private static variables
    var _container;
    var _reservedSlot;
    var _sb;
    var _background;
    var _history;
    var _week;
    var NODE = TESCO.system.DOM.node;

    //  private static functions
    function _setReservedSlot() {
        var _reservedSlots = NODE.getElementsByClassName(_container, "reserved");
        _reservedSlot = (_reservedSlots != null) ? _reservedSlots[0] : null;
        _setActiveWeek();
    }

    function _setActiveWeek() {
        var _weekList = NODE.getElementsByClassName(_container, "weekList")[0];
        var _activeWeek = NODE.getElementsByClassName(_weekList, "active")[0];
        _week = _activeWeek.id.split("-")[1];
    }

    function _slotEntity(id, remove) {
        this.request = {
            deliverySlot: {
                "id": id,
                "remove": remove,
                "week": _week
            }
        };
    }

    function _dateRangeEntity(week) {
        this.request = {
            delivery: {
                "week": week
            }
        };
    }

    function _overlay(container, f) {
        var _b = NODE.getElementsByClassAndTagName(document.body, "deliveryRange", "div")[0];
        _background = new TESCO.UI.effects.Background(_b);
        _background.show()
        TESCO.system.connection.eggTimer.show(NODE.getElementsByClassAndTagName(document.getElementById("deliverySlots"), "background", "div")[0]);
        f();
    }

    function _getControl(node) {
        var _control = {};
        if ((node.nodeName.toUpperCase() == "A") && NODE.getAncestor(node, null, "control")) {
            _control.action = "dateTab";
            _control.node = node;
        } else if (node.nodeName.toUpperCase() == "A" & node.className.indexOf("weekLink") != -1) {
            _control.action = "dateRanger";
            _control.node = node;
        } else if (node.id == "yesHoldSlot") {
            _control.action = "extendDeliverySlot";
            _control.node = node;
        } else if (node.id.indexOf("unreserve") != -1 || node.id == 'removeDeliverySlotReservationLink') {
            _control.action = "removeDeliverySlot";
            _control.node = node;
        } else {
            var _deliveryCell = _getDeliveryCell(node);
            if (_deliveryCell) {
                if (NODE.hasClassName(_deliveryCell, "unavailable") || NODE.hasClassName(_deliveryCell, "booked")) {
                    _control.action = "none";
                } else {
                    _control.action = "deliverySlotAvailable";
                }
                _control.node = _deliveryCell;
                _control.affected = _container;
                _control.id = null;
            }
        }
        return _control;
    }

    function _getDeliveryCell(node) {
        return (node.nodeName.toLowerCase() == "td") ? node : NODE.getAncestor(node, "TD", null, 3);
    }

    function _getDeliverySlotId(node) {
        var _id;
        var _inputs = node.getElementsByTagName("input");
        if (_inputs.length > 0) {
            _id = _inputs[0].id.replace("d-", "");
        }
        return _id;
    }
    //#endregion

    //#region
    //  private instance
    //	change date range
    function _post(url, entity) {    
        var _connection = new TESCO.system.connection.ajax(false);
        var _slots = this;
        if (entity.request.delivery) {
            _history.record(entity.request.delivery.week);
        } else {
            _setActiveWeek();
            _history.record(_week);
        }

        TESCO.system.event.attach(_connection, "complete",
            function(e) {
                _slots.render(e.response.response.content.nodeValue, _container, url);
            }
        );
        TESCO.system.event.attach(_connection, "error",
		    function(e) {
		        _background.hide();
		        TESCO.system.connection.eggTimer.hide(NODE.getElementsByClassAndTagName(document.getElementById("deliverySlots"), "background", "div")[0]);
		        //  show error
		        e.exception.dialogue.show(e.exception);
		    }
		);
        _connection.request(url, entity, TESCO.system.connection.XMLHTTP.METHOD.post, TESCO.system.connection.XMLHTTP.MIMETYPE.xml);
        return true;
    }

    function _dateControlHandler(control) {
        var _node = control.node
        _dateRangeHandler.call(this, parseInt(_node.toString().getValueFromQuery("week")));
    }

    function _dateRangeHandler(weekIndex) {
        if (!isNaN(weekIndex)) {
            var _slots = this;
            _overlay(_container,
				function() {
				    _post.call(_slots, TESCO.sites.Configuration.application.path + "/Ajax/GetDeliveryRange.aspx", new _dateRangeEntity(weekIndex));
				}
			);
        }
    }
    
    //	extend slot
    function _extendSlotHandler(control) {
        var _slots = this;
        var _deliveryEntity = new _slotEntity(_getDeliverySlotId(control.node), false);
        _overlay(_container,
			function() {
			    _post.call(_slots, TESCO.sites.Configuration.application.path + "/Ajax/ExtendDeliverySlot.aspx", _deliveryEntity);
			}
		);
    }
    //#endregion

    //#region
    //  constructor
    function _constructor(id) {
        _container = document.getElementById(id);
        _history = new TESCO.system.connection.ajax.History(id);
        var _staleValue = _history.staleValue();
        if (!!_staleValue) {	//  it’s out of date
            //  update
            _dateRangeHandler.call(this, (parseInt(_staleValue, 10)));
        }
        _setReservedSlot();
        var _slots = this;

        TESCO.system.event.attach(_container, "click",
			function(e) {
			    var _control = _getControl(e.target);
			    if (_control) {
			        switch (_control.action) {
			            case ("dateRanger"):
			            case ("dateTab"):
			                _dateControlHandler.call(_slots, _control);
			                e.prevent();
			                break;
			            case "deliverySlotAvailable":
			                _slots.available(e, _control);
			                e.prevent(); 
			                break;
			            case "extendDeliverySlot":
			                _extendSlotHandler.call(_slots, _control);
			                e.prevent();
			                break;
			            case "removeDeliverySlot":
			                _slots.unreserveSlot(_control);
			                e.prevent();
			                break;
			        }
			    }
			}
		);

        TESCO.system.event.attach(_container, "mouseover",
			function(e) {
			    var _control = _getControl(e.target);
			    if (_control) {
			        if (_control.action == "deliverySlotAvailable") {
			            _slots.highlightSlot(_control.node);
			            e.stopEvent();
			        }
			    }
			}
		);

        TESCO.system.event.attach(_container, "mouseout",
			function(e) {
			    var _control = _getControl(e.target);
			    if (_control) {
			        if (_control.action == "deliverySlotAvailable") {
			            _slots.unHighlightSlot(_control.node);
			            e.stopEvent();
			        }
			    }
			}
		);
        return this;
    }
    //#endregion
    
    _constructor.prototype.NAME = "TESCO.UI.DeliverySlots";

    _constructor.prototype.render = function(html, node) {
        var _b = NODE.getElementsByClassName(document.body, "deliveryRange", "div")[0];
        TESCO.system.connection.eggTimer.hide(NODE.getElementsByClassAndTagName(document.getElementById("deliverySlots"), "background", "div")[0]);
        NODE.removeChildNodes(node);
        node.appendChild(html);
        _setReservedSlot();
    }
    
    _constructor.prototype.highlightSlot = function(node) {
        var _label = NODE.getFirstChildByType(node, "label");
        if (_label) {
            node.style.textDecoration = "underline";
            node.style.cursor = _label.style.cursor = "pointer";
        }
    }

    _constructor.prototype.unHighlightSlot = function(node) {
        var _label = NODE.getFirstChildByType(node, "label");
        if (_label) {
            node.style.textDecoration = "none";
            node.style.cursor = _label.style.cursor = "pointer";
        }
    }
    
    //	delivery slot
    _constructor.prototype.reserveSlot = function(control) {
        var _slots = this;
        var _deliveryEntity = new _slotEntity(_getDeliverySlotId(control.node), control.node == _reservedSlot);
        _overlay(_container,
			function() {
			    _post.call(_slots, TESCO.sites.Configuration.application.path + "/Ajax/ReserveDeliverySlot.aspx", _deliveryEntity);
			}
		);
    }

    //	unreserve slot
    _constructor.prototype.unreserveSlot = function(control) {
        var _slots = this;
        var _deliveryEntity = new _slotEntity(0/*unused*/, true);
        _overlay(_container,
			function() {
			    _post.call(_slots, TESCO.sites.Configuration.application.path + "/Ajax/UnreserveDeliverySlot.aspx", _deliveryEntity);
			}
		);
    }

    _constructor.prototype.available = function(e, control) {
       var _typeOfCell = NODE.getAction([{ val: 'amendbooked', className: 'amendbooked', depth: 5 }, { val: 'reserved', className: 'reserved', depth: 5}], e.target);
        if (_typeOfCell != 'amendbooked') {
            control.node = (_typeOfCell == 'reserved') ? this.unreserveSlot(control) : this.reserveSlot(control);
        }
    }
    
    //  return constructor as function pointer
    return _constructor;
})();
