﻿if (typeof Effect == "undefined") {	Effect = {}; }

Element.addMethods({
	/**
	 *  Element#cloak(@element) -> element
	 **/
	cloak: function(element) {
		element.style.visibility = "hidden";
	},
	/**
	 *  Element#reveal(element) -> element
	 **/
	reveal: function(element) {
		element.style.visibility = "visible";
	},
	/**
	 *  Element#cloaked(@element) -> Boolean
	 **/
	cloaked: function(element) {
		return element.style.visibility == "hidden";
	}
});

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
            // 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').first().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
         /*   this.contentTarget.setStyle({
                width: width + "px",
                height: height + "px"
            });
        */
            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];
                    }
                });
            }

            this.contentTarget.update(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]"; }
    })
};

// new controller for handling swfs
var SwfController = Class.create(BoxBox.Controller, {
    initialize: function($super, defaults) {
        $super();
        this.defaults = defaults;
        this.isEmbedded = false;

    },

    open: function($super) {
        $super();

        if (this.isEmbedded == false && swfobject instanceof Object) {

            swfobject.embedSWF(
                this.defaults.swfOptions.swf,
                this.defaults.swfOptions.id,
                this.defaults.swfOptions.dimensions.width,
                this.defaults.swfOptions.dimensions.height,
                this.defaults.swfOptions.version,
                false,
                this.defaults.swfOptions.flashvars,
                this.defaults.swfOptions.params,
                this.defaults.swfOptions.attributes
            );
            this.isEmbedded == true;
            // IE6 requires a width set
            this.window.wrapper.style.width = this.defaults.swfOptions.dimensions.width+"px";
        }

        // wait for swf to be embedded. Takes about 2 seconds.
        var timer = setTimeout(function() {
            // playVideo is an external interface call. Naming is same with Pop's swf player and youtubes
            $(this.defaults.swfOptions.id).playVideo();
        }.bind(this), 2000);

    },

    close: function($super) {
        $super();
        // stopVideo is an external interface call. Naming is same with Pop's swf player and youtubes
        $(this.defaults.swfOptions.id).stopVideo();
    }
});


// WINDOW DEFAULTS
Object.extend(BoxBox.Window, {
	Defaults: {
		duration: 0.25,
		width: 'auto',
		height: 'auto'
	}
});

// OVERLAY DEFAULTS
Object.extend(BoxBox.Overlay, {
	Defaults: {
		background: "#000",
		transition: Effect.Transitions.sinoidal,
		duration: 1
	}
});







