﻿Type.registerNamespace("Cvent.JS.Events");

(function() {
    var nmCal = Cvent.JS.Events;

    /*   ToDo: Need to be replaced by some JS Library function like prototype.js 1.6.1 or JQuery */
    function pageWidth() {
        return window.innerWidth != null ? window.innerWidth : document.documentElement && document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body != null ? document.body.clientWidth : null;
    }
    function pageHeight() {
        return window.innerHeight != null ? window.innerHeight : document.documentElement && document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body != null ? document.body.clientHeight : null;
    }
    function posLeft() {
        return typeof window.pageXOffset != 'undefined' ? window.pageXOffset : document.documentElement && document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ? document.body.scrollLeft : 0;
    }
    function posTop() {
        return typeof window.pageYOffset != 'undefined' ? window.pageYOffset : document.documentElement && document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ? document.body.scrollTop : 0;
    }
    function posRight() {
        return posLeft() + pageWidth();
    }
    function posBottom() {
        return posTop() + pageHeight();
    }

    ///<summary>Enumeration for Calendar Mode.</summary>
    nmCal.CalendarMode = {
        Calendar: 1,
        OneWeek: 2,
        TwoWeek: 3,
        FourWeek: 4,
        ThreeMonth: 5,
        OneYear: 6,
        WeekDay: 7
    };
    /***************************/
    /***************************/
    /* Calendar Class. */
    nmCal.Calendar = function(ContainerID, Mode, ModeType, IsHoverEnabled, fnDataGetterForHover) {
        this.ContainerID = ContainerID;
        this.CalendarMode = Mode;
        this.CalendarModeType = ModeType;
        this.IsHoverEnabled = IsHoverEnabled;
        this.fnDataGetterForHover = fnDataGetterForHover;
        this.Container = $get(this.ContainerID);
        this.CalendarHover = null;
        if (this.Container)
            this.init(); //Can be treated as constructor.
    };
    nmCal.Calendar.prototype = {
        init: function() {
            if (this.IsHoverEnabled) {
                this.CalendarHover = new nmCal.CalendarHover("dvCalendarAjaxPopUp", this, "#" + this.ContainerID + " .calLinks a[evtStub]", this.fnDataGetterForHover);
            }
        }
    };
    ///<summary> Helps us to redirect to corresponding event or to corresponding URL.</summary>
    nmCal.Event = {
        Redirect: function(pageUrl, IsCventUrl) {
            if (pageUrl == "")
                return void (1);
            window.open(pageUrl);
        }
    };
    /***************************/
    /***************************/
    /*<summary>Calendar Hover Class.</summary>*/
    nmCal.CalendarHover = function(dvCalendarAjaxPopUpId, SelectorRule, ParentCssClass, fnDataGetter) {
        this.dvCalendarAjaxPopUpId = dvCalendarAjaxPopUpId;
        var aElements = $$(SelectorRule); //ToDo: Use Other function for $$ (Prototype.js)
        this.width = 320;                           //Change Width to appropriate value.
        this.fnDataGetter = fnDataGetter;
        this.dvCalendarAjaxPopUp = $(dvCalendarAjaxPopUpId);
        this.dvCalendarAjaxPopUp.style.width = this.width + "px";
        this.dvCalendarAjaxPopUp.CurrentTrigger = null;
        this.ParentCssClass = ParentCssClass;
        this.fnDataGetterSuccess = Function.createDelegate(this, this.onDataGetterSuccess);
        this.fnDataGetterFailure = Function.createDelegate(this, this.onDataGetterFailure);
        for (var i = 0; i < aElements.length; i++) {
            var OnCalLinkMouseOver = Function.createDelegate(this, this.OnLinkMouseOver);
            var OnCalLinkMouseOut = Function.createDelegate(this, this.OnLinkMouseOut);
            $addHandler(aElements[i], 'mouseover', OnCalLinkMouseOver);
            $addHandler(aElements[i], 'mouseout', OnCalLinkMouseOut);
        }
    };

    nmCal.CalendarHover.prototype = {
        ShowPopUp: function(sourceElement) {
            var ancBounds = this.AdjustPopUpPosition(sourceElement);
            this.dvCalendarAjaxPopUp.style.display = 'block';
            var bounds = Sys.UI.DomElement.getBounds(this.dvCalendarAjaxPopUp);
            //Checking if Div is in the bottom of the page.
            if (posBottom() < (bounds.y + bounds.height)) {
                this.dvCalendarAjaxPopUp.setStyle({
                    top: (bounds.y - bounds.height - ancBounds.height) + 'px'
                });
            }
            //Checking if Div is in the right of the page.
            if (posRight() < (bounds.x + bounds.width)) {
                this.dvCalendarAjaxPopUp.setStyle({
                    left: (bounds.x - bounds.width + ancBounds.width) + 'px'
                });
            }
        },
        FillPopUp: function(content) {
            this.dvCalendarAjaxPopUp.innerHTML = content;
        },
        HidePopUp: function() {
            this.dvCalendarAjaxPopUp.style.display = 'none';
            this.dvCalendarAjaxPopUp.CurrentTrigger = null;
        },
        AdjustPopUpPosition: function(sourceElement) {
            var prNode = sourceElement;
            var prAnchor = null;
            if (this.ParentCssClass && this.ParentCssClass != "") {
                while (prNode && prNode.className != this.ParentCssClass) {
                    prNode = prNode.parentNode;
                }
            } else {
                while (prNode.tagName.toLowerCase() != "tr"
						&& prNode.tagName.toLowerCase() != "div") {
                    if (prAnchor == null && prNode.tagName.toLowerCase() == "a")
                        prAnchor = prNode;
                    prNode = prNode.parentNode;
                }
            }

            var bounds = Sys.UI.DomElement.getBounds(prNode);
            var offst = j$(prNode).offset();
            bounds.x = offst.left; bounds.y = offst.top;
            if (prAnchor != null) {
                bounds.x = j$(prAnchor).offset().left;
            }

            ////////////ToDo: Prototype.js Implementation.
            this.dvCalendarAjaxPopUp.setStyle({
                left: bounds.x + 'px',
                top: (bounds.y + bounds.height) + 'px'
            });
            return bounds;
        },
        OnLinkMouseOver: function(e) {
            var el = Event.element(e);
            this.dvCalendarAjaxPopUp.CurrentTrigger = el;

            if (el.content) {
                this.FillPopUp(el.content);
                this.ShowPopUp(el);
            }
            else {
                var e = el.attributes["e"].nodeValue;
                var c = el.attributes["c"].nodeValue;
                var p = el.attributes["p"].nodeValue;
                var t = el.attributes["t"].nodeValue;
                var l = el.attributes["l"].nodeValue;
                this.FillPopUp("Loading...");
                this.ShowPopUp(el);
                this.fnDataGetter(c, e, p, t,l, this.fnDataGetterSuccess, this.fnDataGetterFailure, el);
            }
        },
        OnLinkMouseOut: function(e) {
            this.HidePopUp();
        },
        onDataGetterSuccess: function(response, context, m) {
            if (context) {
                if (response == "") {
                    context.content = "<strong>No additional information found.</strong>";
                }
                else {
                    context.content = response;
                }
            }
            if (this.dvCalendarAjaxPopUp.CurrentTrigger == context) {
                this.FillPopUp(context.content);
                this.ShowPopUp(context);
            }
        },
        onDataGetterFailure: function(response, context) {

        }
    };
    nmCal.CalendarHover.registerClass('Cvent.JS.Events.CalendarHover');
    nmCal.Calendar.registerClass('Cvent.JS.Events.Calendar');
})();
