﻿/// <reference path="jquery-1.3.2-vsdoc.js" />


var MultiModal = {};

MultiModal = JClass.extend({
    init: function (settings) {
        // do initialization here
        if (typeof(settings.target) === 'string')
            if (settings.target.substr(0, 1) != '#')
                settings.target = jQuery('#' + settings.target)[0];


        this._ModalWrapper = settings.target;
        this._Modal = document.createElement('div');
        this.overlay = document.createElement('div');
        this.children = new Array();
        this._PrepCalled = false;
        this.currentSettings =
        {
            //Properties
            target: settings.target, //Works
            height: null, //Not Yet
            width: null, //Not Yet
            minHeight: null, //Not Yet
            minWidth: null, //Not Yet
            escapeToClose: true, //Works
            overlayClickToClose: true, //Works
            overlayClass: 'ModalOverlay', //Works
            autoResize: true, //Works
            draggable: true, //Works
            nonContentHeight: 90, //Works
            nonContentWidth: 85,
            resetPositionOnShow: true, //Works
            title: null,
            //Events
            onShow: null, //Not Yet
            onHide: null, //Not Yet

            //Other
            topWrapperSelector: '#ModalTop',
            headerSelector: '#ModalTop div.TopRepeat',
            contentSelector: '#ModalContent div.ContentRepeat',
            closeSelector: 'div.ModalCloseBut a.ModalCloseBut'
        };

        this.currentSettings = jQuery.extend(true, {}, this.currentSettings, settings);

        this._Dimensions = null;
        this._Ref = null;
        this._IsMoved = false;
        this._Closing = false;
        this.Prep();
    },
    Prep: function () {
        //This function preps the area to be a modal by injecting all the required elements around it
        if (this._PrepCalled || jQuery(this.currentSettings.target).hasClass("MultiModal"))
            return;
        this._PrepCalled = true;
        jQuery(this.currentSettings.target).addClass("MultiModal");
        var content = this.GetWrapper();

        //Instances are not kept during anonymous functions
        var modal = this._Modal;
        var overlay = this.overlay;
        var children = this.children;

        jQuery.each(jQuery(this._ModalWrapper).children(), function (i, v) {
            //Clone all elements
            children.push(jQuery(v).clone(true));
            //Remove the elements
            jQuery(v).remove();
        });

        jQuery(this._ModalWrapper).append(modal);
        jQuery(this._ModalWrapper).append(overlay);

        //Click overlay to close
        if (this.currentSettings.overlayClickToClose) {
            var hide = Function.createDelegate(this, this.Hide);
            jQuery(overlay).click(function () {
                hide();
            });
        }

        //Prep the modal styles and the overlay styles
        modal.style.position = 'absolute';
        jQuery(overlay).addClass(this.currentSettings.overlayClass);
        jQuery.each(this.children, function (i, v) { jQuery(content).append(v); });
    },
    CreateElement: function (element, id, classname) {
        var e = document.createElement(element);
        jQuery(e).attr("class", classname);
        jQuery(e).attr("id", id);

        return e;
    },
    GetWrapper: function () {

        //The modal sides need to be added in this order
        var enhancedModalHTML =
                                    "<div class='ModalCloseBut'><a class='ModalCloseBut'></a></div>" +
                                    "<div id='ModalTop'>" +
			                        "    <div class='TopLeft'><div class='TopRight'><div class='TopRepeat'><span class='top'>" + this.currentSettings.title + "</span></div></div></div>" +
		                            "</div>" +

		                            //"<div id='ModalHeader'><div class='HeaderLeft'><div class='HeaderRight'><div class='HeaderRepeat'>" +
			                        //"    <span class='top'>" + this.currentSettings.title + "</span>" + // "</div></div></div>" +
		                            //"</div>" +

		                            "<div id='ModalContent'>" +
			                        "    <div class='ContentLeft'><div class='ContentRight'><div class='ContentRepeat'></div></div></div>" +
		                            "</div>" +

		                            "<div id='ModalBottom'>" +
			                        "    <div class='BottomLeft'><div class='BottomRight'><div class='BottomRepeat'>" +
                                    "</div></div></div>" +
		                            "</div>"

        jQuery(this._Modal).append(enhancedModalHTML);

        var hide = Function.createDelegate(this, this.Hide);
        jQuery(this._Modal).find(this.currentSettings.closeSelector).click(function () {
            hide();
        });

        if (this.currentSettings.draggable) {
            //Make Draggable 
            jQuery(this._Modal).draggable({
                handle: jQuery(this._Modal).find(this.currentSettings.topWrapperSelector),
                stop: Function.createDelegate(this, this._OnDragComplete)
            });
            //Make the double click reset the Modal
            jQuery(this._Modal).find(this.currentSettings.topWrapperSelector).dblclick(Function.createDelegate(this, this._OnDoubleClick));
        }
        var val = jQuery(this._Modal).find(this.currentSettings.contentSelector);
        return val;

    },
    Clone: function () {

        //Instances are not kept during anonymous functions
        var modal = this._Modal;
        var overlay = this.overlay;
        var children = this.children;

        jQuery.each(jQuery(modal).children(), function (i, v) { jQuery(v).remove(); });
        jQuery.each(this.children, function (i, v) { jQuery(modal).append(v); });
    },
    Show: function () {
        //Update MultiModal Objects
        var zIndexes = MultiModal.GetZIndex();
        this._Ref = { Modal: this, modalZIndex: zIndexes.modalIndex, overlayIndex: zIndexes.overlayIndex };
        MultiModal.ModalList.push(this._Ref);

        if (this.currentSettings.resetPositionOnShow)
            this._IsMoved = false;

        //Instances are not kept during anonymous functions
        var modal = this._Modal;
        var overlay = this.overlay;
        modal.style.zIndex = zIndexes.modalIndex;

        jQuery(overlay).css('zIndex', zIndexes.overlayIndex);

        //Set the title
        //jQuery(modal).find(this.currentSettings.headerSelector).html(this.currentSettings.title);

        jQuery(this._ModalWrapper).show();
        this._ResizeCallback();
        modal.style.display = "none";
        jQuery(modal).slideDown('slow');
        overlay.style.display = "block";
        jQuery(overlay).css({ opacity: 0 }).fadeTo(500, 0.30, null);

        // Calculate position for modal
        jQuery(window).bind('resize', Function.createDelegate(this, this._ResizeCallback));


    },
    Hide: function () {
        MultiModal.Remove(true);
    },
    _Hide: function () {


        this._Closing = true;
        jQuery(window).unbind('resize', Function.createDelegate(this, this._ResizeCallback));

        var modal = this._Modal;
        var overlay = this.overlay;
        var ModalWrapper = this._ModalWrapper;


        jQuery(modal).slideUp('slow', function () { jQuery(ModalWrapper).hide(); });
        //jQuery(overlay).fadeOut('slow', Function.createDelegate(this, this._OnHideComplete));
        jQuery(overlay).css({ opacity: .30 }).fadeTo(500, 0, Function.createDelegate(this, this._OnHideComplete));
    },
    //Callback functions
    _OnHideComplete: function () {
        this._Closing = false;
        MultiModal.ModalList.pop();

        //if (MultiModal.ModalList.length == 0)
        //    document.body.style.overflow = "auto";

    },
    _OnDragComplete: function () {
        this._IsMoved = true;
    },
    _OnDoubleClick: function () {
        this._IsMoved = false;
        this._ResizeCallback();
    },
    _ResizeCallback: function () {

        //Instances are not kept during anonymous functions
        var modal = this._Modal;
        var overlay = this.overlay;

        //If modal was moved don't recenter in browser or change width/height
        if (!this._IsMoved) {

            //Set the correct location for the modal
            var dimensions =
             {
                 'modalHeight': jQuery(modal).outerHeight(true),
                 'modalWidth': jQuery(modal).outerWidth(true),
                 'contentHeight': jQuery(modal).find(this.currentSettings.contentSelector).outerHeight(true),
                 'contentWidth': jQuery(modal).find(this.currentSettings.contentSelector).outerWidth(true),
                 'winHeight': jQuery(window).height(),
                 'winWidth': jQuery(window).width()
             };
            if (this._Dimensions == null) {
                this._Dimensions = dimensions;
                if (this.currentSettings.height != null) {
                    jQuery(modal).find(this.currentSettings.contentSelector).css('height', this.currentSettings.height - this.currentSettings.nonContentHeight);
                }

            }

            var heightChange = true;
            //        //Set the correct width and height if the modal is large than the window
            if (this.currentSettings.height != null) {
                jQuery(modal).css('height', this.currentSettings.height); //- this.currentSettings.nonContentHeight);
                //Check overflow
                jQuery(modal).find(this.currentSettings.contentSelector).css('height', this.currentSettings.height - this.currentSettings.nonContentHeight); //Subtract the modals top and bottom areas
                jQuery(modal).find(this.currentSettings.contentSelector).css("overflow", "auto");

            }
            else if (dimensions.modalHeight >= dimensions.winHeight) {
                jQuery(modal).css('height', dimensions.winHeight);
                jQuery(modal).find(this.currentSettings.contentSelector).css('height', dimensions.winHeight - this.currentSettings.nonContentHeight); //Subtract the modals top and bottom areas
                jQuery(modal).find(this.currentSettings.contentSelector).css("overflow", "auto");
            } else if (dimensions.contentHeight < this._Dimensions.contentHeight) {
                jQuery(modal).css('height', Math.min(dimensions.winHeight, this._Dimensions.modalHeight));
                jQuery(modal).find(this.currentSettings.contentSelector).css('height', Math.min(dimensions.winHeight, this._Dimensions.contentHeight));
            } else {
                heightChange = false;
            }


            var widthChange = true;
            if (this.currentSettings.width != null) {
                jQuery(modal).css('width', this.currentSettings.width); //+ this.currentSettings.nonContentWidth);
            }
            else if (dimensions.modalWidth >= dimensions.winWidth) {
                jQuery(modal).css('width', dimensions.winWidth);
                jQuery(modal).find(this.currentSettings.contentSelector).css("overflow", "auto");
            } else if (dimensions.contentWidth < this._Dimensions.contentWidth) {
                jQuery(modal).css('width', Math.min(dimensions.winWidth, this._Dimensions.contentWidth));
            }
            else {
                widthChange = false;
            }

            if (!widthChange && !heightChange)
                jQuery(this.currentSettings.contentSelector).css("overflow", "hidden");

            dimensions =
             {
                 'modalHeight': jQuery(modal).outerHeight(true),
                 'modalWidth': jQuery(modal).outerWidth(true),
                 'contentHeight': jQuery(modal).find(this.currentSettings.contentSelector).outerHeight(true),
                 'contentWidth': jQuery(modal).find(this.currentSettings.contentSelector).outerWidth(true),
                 'winHeight': jQuery(window).height(),
                 'winWidth': jQuery(window).width()
             };

            //Adjust the top and left (I don't why I should divide so much)
            var top = (dimensions.winHeight - dimensions.modalHeight) / 2;
            var left = (dimensions.winWidth - dimensions.modalWidth) / 2;
            jQuery(modal).css('top', top + jQuery(window).scrollTop());
            jQuery(modal).css('left', left);
        }

    },
    _CreateWrapper: function () {
    },
    _RemoveWrapper: function () {
    }
});



MultiModal.ModalList = new Array();

MultiModal.GetZIndex = function () {
    var zIndexs = { overlayIndex: 100, modalIndex: 101 };

    zIndexs.modalIndex = zIndexs.modalIndex + (MultiModal.ModalList.length * 2);
    zIndexs.overlayIndex = zIndexs.overlayIndex + (MultiModal.ModalList.length * 2);

    return zIndexs;
}
MultiModal.Remove = function (hide) {
    var object = MultiModal.ModalList[MultiModal.ModalList.length - 1];
    if (hide && object.Modal._Closing == false)
        object.Modal._Hide();

}

jQuery(function () {
    jQuery(document).keyup(function (e) {
        if (MultiModal.ModalList.length > 0) {
            var object = MultiModal.ModalList[MultiModal.ModalList.length - 1];

            if ((e.keyCode == 27 || e.which == 27) && object.Modal.currentSettings.escapeToClose == true) {
                MultiModal.Remove(true);
            }
        }
    });
});
