﻿if (typeof Effect == "undefined") {	Effect = {}; }

/*Element.cloak moved to scripts.js*/

var BoxBox = {
    Overlay: Class.create({
        initialize: function(defaults) {
            // Set defaults based on class defaults and user input. These can be overridden at runtime.
            this.defaults = Object.extend(Object.clone(BoxBox.Overlay.Defaults), defaults || {});

            // for the styles below, i moved position into css as ie6 needs absolute, not fixed. ie6 check needs to be built into this boxbox. BF
            this.element = new Element("div", { "class": "bb-overlay" }).setStyle({
                display: "none",
                width: "100%", height: "100%",
                left: 0, top: 0,
                background: this.defaults.background
            });
            
            $(document.body).insert({ top: this.element }); // Should this go up top?
        },
        /**
        *  BoxBox.Overlay#show() -> this
        **/
        show: function() {
            // TODO: allow passing runtime options which override defaults
        	//!!! ie6 hack
			var IE6 = false/*@cc_on || @_jscript_version < 5.7@*/;
			if(IE6){
				this.element.setStyle({'height' : $(document.body).getHeight()});
			}
			//!!! ie6 hack
            // Fade-in overlay
            new Effect.Appear(this.element, {
                to: "0.8",
                transition: this.defaults.transition,
                duration: this.defaults.duration,
                afterFinish: function(fx) {
                    $(document).fire("boxbox:overlay:appear", {
                        effect: fx,
                        sender: this
                    });

                } .bind(this)
            });
            return this;
        },
        /**
        *  BoxBox.Overlay#hide() -> this
        **/
        hide: function() {
            // Fade-out overlay
            new Effect.Fade(this.element, {
                transition: this.defaults.transition,
                duration: this.defaults.duration,
                afterFinish: function(fx) {
                    $(document).fire("boxbox:overlay:fade", {
                        effect: fx,
                        sender: this
                    });
                } .bind(this)
            });
            return this;
        },
        /**
        *  BoxBox.Overlay#visible() -> Boolean
        **/
        visible: function() {
            return this.element.visible();
        },
        /**
        *  BoxBox.Overlay#toString() -> String
        **/
        toString: function() { return "[object BoxBox.Overlay]"; }
    }),

    Window: Class.create({
        initialize: function(defaults) {
            // Set defaults based on class defaults and user input. These can be overridden at runtime.
            this.defaults = Object.extend(Object.clone(BoxBox.Window.Defaults), defaults || {});

            // Create and insert default elements
            this.wrapper = new Element("div", { "class": "bb-wrapper", style: "display:none; position:absolute;" });
            
            $$('body')[0].insert({ top: this.wrapper });
            this.contentTarget = new Element("div", { "class": "bb-content-target" });
            this.wrapper.insert(this.contentTarget);
        },

        //
        // API: Public Methods
        //

        /**
        *  BoxBox.Window#show() -> this
        **/
        show: function(content, options) {
            var options = Object.extend(Object.clone(this.defaults), options || {});

            if (content) {
                // Set content if provided
                this.setContent(content);
            }

            // Find width and height of CONTENT
            var viewPortWidthHeight = document.viewport.getDimensions();
            var width = Math.min(viewPortWidthHeight.width, options.width);
            var height = Math.min(viewPortWidthHeight.height, options.height);

            // Resize CONTENT
			// Alex had this commented out
			/*
            this.contentTarget.setStyle({
                width: width + "px",
                height: height + "px"
            });
        	*/
			//!!! ie8 fix [tw]
            this.contentTarget.setStyle('width: #{w};height:#{h};'.interpolate({w:width, h: height}));
            //!!!//			
			
            this._center();

            // Show the elements
            this.wrapper.show();
            this.contentTarget.reveal();
            return this;


        },
        /**
        *  BoxBox.Window#hide() -> this
        **/
        hide: function() {
            this.wrapper.hide();
            this.contentTarget.cloak();
            return this;
        },
        /**
        *  BoxBox.Window#resize(width, height) -> this
        **/
        resize: function(width, height) {
            // Find width and height of CONTENT
            var viewPortWidthHeight = $(document).viewport.getDimensions();
            var width = Math.min(viewPortWidthHeight.width, width);
            var height = Math.min(viewPortWidthHeight.height, height);

            new Effect.Morph(this.contentTarget, {
                style: {
                    width: width + "px",
                    height: height + "px"
                },
                duration: this.defaults.duration,
                afterUpdate: function(e) {
                    this._center();
                } .bind(this),
                queue: { position: 'end', scope: 'boxbox' }
            });
            return this;
        },
        /**
        *  BoxBox.Window#resizeToContent() -> this
        **/
        resizeToContent: function() {
            throw "Not implemented";
            return this;
        },
        /**
        *  BoxBox.Window#visible() -> Boolean
        **/
        visible: function() {
            return this.wrapper.visible() && !this.contentTarget.cloaked();
        },

        /**
        *  BoxBox.Window#setContent(content[, type]]) -> this
        **/
        setContent: function(content, type) {
            // TYPE will determine how the content is treated. Otherwise we try to discern it (think url string vs iframe url)
            if (false) {
                [["previous", "after"], ["next", "before"], ["up", "bottom"]].each(function(position) {
                    if (content[position[0]]()) {
                        var rel = content[position[0]]();
                        var dir = position[1];
                    }
                });
            }
			
			//!!! move any existing content back to it's previous location. [tw]
			var isSameContent = content.descendantOf(this.contentTarget);
			
			if(this.contentTarget.empty() == false){
				var elExistingContent = this.contentTarget.down();
				if(!isSameContent){
					if ('_prevID' in elExistingContent) {
						//console.log('putting content back to previous', elExistingContent._prevID);
						$(elExistingContent._prevID).insert({after: elExistingContent});
					} else if ('_parentID' in elExistingContent) {
						//console.log('putting content back to parent', elExistingContent._parentID);
						$(elExistingContent._parentID).insert({top: elExistingContent});
					}					
				}
			}
		
			if(!('_prevID' in content) && !('_parentID' in content)){
				if(Object.isElement(content.previous())){
					content._prevID = content.previous().identify();
					//console.log('setting previous to ', content._prevID.id);
				} else {
					content._parentID = content.up().identify();
					//console.log('setting parent to ', content._parentID)
				}
			}

            this.contentTarget.insert(content);
			//!!!//

            return this;
        },

        //
        // Private Methods
        //

        /**
        *  BoxBox.Window#_getContentSize()() -> Array
        **/
        _getContentSize: function() {
            throw "Not implemented";
        },

        _center: function() {
            var viewPortWidthHeight = $(document).viewport.getDimensions();

            // Find new position of WRAPPER
            var boxWidthHeight = this.wrapper.getDimensions();
            var left = Math.max(0, (viewPortWidthHeight.width - boxWidthHeight.width) / 2) + document.documentElement.scrollLeft;
            var top = Math.max(0, (viewPortWidthHeight.height - boxWidthHeight.height) / 2) + document.documentElement.scrollTop;

            // Position WRAPPER
            this.wrapper.setStyle({ left: left + "px", top: top + "px" });
        },

        /**
        *  BoxBox.Window#toString() -> String
        **/
        toString: function() { return "[object BoxBox.Window]"; }
    }),

    Controller: Class.create({
        initialize: function() {
            this.overlay = new BoxBox.Overlay();
            this.window = new BoxBox.Window();
        },
        open: function(content, options) {
            this.overlay.show();

            // Open window when overlay should be open
            setTimeout(function() {
                this.window.show(content);
            } .bind(this), this.overlay.defaults.duration * 1000);

            return this;
        },
        close: function() {
            this.window.hide();
            this.overlay.hide();
            return this;
        },
        resize: function(width, height) {
            if (typeof height == "undefined") {
                height = width;
            }
            this.window.resize(width, height);
            return this;
        },
        resizeToContent: function() {
            throw "Not implemented";
        },
        /**
        *  BoxBox.Controller#toString() -> String
        **/
        toString: function() { return "[object BoxBox.Controller]"; }
    })
};


// WINDOW DEFAULTS
Object.extend(BoxBox.Window, {
	Defaults: {
		duration: 0.25,
		width: 'auto', // 800
		height: 'auto' //'auto' 550
	}
});

// OVERLAY DEFAULTS
Object.extend(BoxBox.Overlay, {
	Defaults: {
		background: "#000",
		transition: Effect.Transitions.sinoidal,
		duration: 0.5
	}
});