/*  Copyright OrangeLime Studio 2009
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation. This program is distributed in the hope that
    it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details <http://www.gnu.org/licenses/>.
*/
function olsLightbox(id) {
    this.id = id;
    if (!document.getElementById("lightbox")) init();
    this.underlayDarkness = 80;
    this.growTimeSpan = 250;
    this.fadeTimeSpan = 250;
    this.initHeight = 200;
    this.initWidth = 500;
    this.object = document.getElementById(id);
    this.objectParent = this.object.parentNode;
    this.lightbox = document.getElementById('lightbox');
    this.underlay = document.getElementById('lightboxUnderlay');
    this.container = document.getElementById('lightboxContainer');
    this.content =  document.getElementById('lightboxContent');
    this.control =  document.getElementById('lightboxControl');
    this.dimensions = new Dimensions();
    this.open =
        function (mode) {
            var oldFloat = this.control.style.styleFloat;
            this.control.style.styleFloat = 'none';
            if (isIE6orLess()) {
                this.boxHeight = this.object.defaultHeight;
                this.boxWidth = this.object.defaultWidth;
            }
            else {
                this.object.style.display = 'block';
                this.boxHeight = this.object.clientHeight+this.container.clientHeight;
                this.boxWidth = Math.max(this.object.clientWidth,this.container.clientWidth)-3;
            }
            this.control.style.styleFloat = oldFloat;
            this.underlay.style.height = this.dimensions.pageHeight()+'px';
            this.underlay.style.display = 'block';
            disableRecalcitrants();
            window.olsLightbox = this;
            window.changeStyleValue = this.changeStyleValue;
            if (mode == "animate") {
                animateStyle('lightboxUnderlay','opacity',0,this.underlayDarkness,this.fadeTimeSpan,
                    function () {
                        this.olsLightbox.boxOpen();
                    });
            }
            else {
                animateStyle('lightboxUnderlay','opacity',0,this.underlayDarkness,this.fadeTimeSpan,
                    function () {
                        this.olsLightbox.boxFadeOpen();
                    });
            }
        };
    this.boxFadeOpen =
        function () {
            this.lightbox.style.top = this.dimensions.pageScrolledDown() + Math.round((this.dimensions.windowHeight()-this.boxHeight)/3)+"px";
            this.lightbox.style.left = this.dimensions.pageScrolledRight() + Math.round((this.dimensions.windowWidth()-this.boxWidth)/2)+"px";
            this.lightbox.style.height = this.boxHeight+'px';
            this.lightbox.style.width = this.boxWidth+'px';
            var object = this.objectParent.removeChild(this.object);
            this.content.appendChild(object);
            object.style.display = 'block';
            object.style.visibility = 'visible';
            object.style.position = 'static';
            this.lightbox.style.visibility = 'visible';
            this.container.style.visibility = 'visible';
            changeStyleValue('lightboxContainer','opacity',100);
            animateStyle('lightbox','opacity',0,100,this.fadeTimeSpan);
        }
    this.boxOpen =
        function () {
            this.lightbox.style.top = this.dimensions.pageScrolledDown() + Math.round((this.dimensions.windowHeight()-this.boxHeight)/3)+"px";
            this.lightbox.style.left = this.dimensions.pageScrolledRight() + Math.round((this.dimensions.windowWidth()-this.boxWidth)/2)+"px";
            this.lightbox.style.height = this.initHeight+'px';
            this.lightbox.style.width = this.initWidth+'px';
            this.lightbox.style.visibility = 'visible';
            animateStyle('lightbox','opacity',0,100,this.fadeTimeSpan,
                function () {
                    this.olsLightbox.boxGrowHeight();
                });
        };
    this.boxGrowHeight =
        function () {
            animateStyle('lightbox','height',this.lightbox.clientHeight,this.boxHeight,this.growTimeSpan,
                function () {
                    this.olsLightbox.boxGrowWidth();
                });
        }
    this.boxGrowWidth =
        function () {
            animateStyle('lightbox','width',this.lightbox.clientWidth,this.boxWidth,this.growTimeSpan,
                function () {
                    this.olsLightbox.addContent()
                });
        }
    this.addContent =
        function () {
            var object = this.objectParent.removeChild(this.object);
            this.content.appendChild(object);
            object.style.display = 'block';
            object.style.visibility = 'visible';
            object.style.position = 'static';
            this.container.style.visibility = 'visible';
            animateStyle('lightboxContainer','opacity',0,100,this.fadeTimeSpan);
        };
    this.close =
        function () {
            window.olsLightbox = this;
            window.changeStyleValue = this.changeStyleValue;
            animateStyle('lightbox','opacity',100,0,this.fadeTimeSpan,
                     function () {
                         this.olsLightbox.boxHide();
                     });
        };
    this.boxHide =
        function () {
            this.lightbox.style.visibility = 'hidden';
            this.lightbox.style.height = 'auto';
            this.lightbox.style.width = 'auto';
            var object = this.content.removeChild(this.object);
            object.style.visibility = 'hidden';
            object.style.display = 'none';
            this.objectParent.appendChild(object);
            this.container.style.width = 'auto';
            this.container.style.visibility = 'hidden';
            animateStyle('lightboxUnderlay','opacity',this.underlayDarkness,0,this.fadeTimeSpan,
                function () {
                    this.olsLightbox.underlayHide();
              });
        };
    this.underlayHide =
        function () {
            this.underlay.style.display = 'none';
            enableRecalcitrants();
            changeStyleValue('lightboxContainer','opacity',0);
        };
    function disableRecalcitrants() {
        var plugins = Array(document.getElementsByTagName('embed'),document.getElementsByTagName('object'));
        if (plugins)
            for (var i=0; i<plugins.length; i++)
                for (var j=0; j < plugins[i].length; j++) {
                    plugins[i][j].prevVisibility = plugins[i][j].style.visibility;
                    plugins[i][j].style.visibility = 'hidden';
                }
	var selects = document.getElementsByTagName("select");
        for (var i = 0; i < selects.length; i++) {
                selects[i].prevVisibility = selects[i].style.visibility;
                selects[i].style.visibility = "hidden";
        }
    }
    function enableRecalcitrants() {
        var plugins = Array(document.getElementsByTagName('embed'),document.getElementsByTagName('object'));
        if (plugins)
            for (var i=0; i<plugins.length; i++)
                for (var j=0; j < plugins[i].length; j++) {
                    plugins[i][j].style.visibility = plugins[i][j].prevVisibility;
                    try { delete plugins[i][j].prevVisibility; }
                    catch (e) { plugins[i][j].prevVisibility = null; }
                }
	var selects = document.getElementsByTagName("select");
        for (var i = 0; i < selects.length; i++) {
                selects[i].style.visibility = selects[i].prevVisibility;
                try { delete selects[i].prevVisibility; }
                catch (e) { selects[i].prevVisibility = null; }
        }
    }
    function animateStyle(id, styleProperty, startValue, endValue, millisec, followUpAction) {
        //speed for each frame
        var speed = Math.round(millisec/100);
        var timer = 0;

        //determine the direction for the blending, if start and end are the same nothing happens
        if(startValue > endValue) {
            for(i = startValue; i >= endValue; i--) {
                setTimeout("changeStyleValue('"+id+"','"+styleProperty+"',"+i+","+(i-1 < endValue?followUpAction:null)+")",(timer * speed));
                timer++;
            }
        }
        else {
            for(i = startValue; i <= endValue; i++) {
                setTimeout("changeStyleValue('"+id+"','"+styleProperty+"',"+i+","+(i+1 > endValue?followUpAction:null)+")",(timer * speed));
                timer++;
            }
        }
    }
    this.changeStyleValue =
        function (id, styleProperty, value, followUpAction) {
            var object = document.getElementById(id).style;
            switch (styleProperty) {
                case "opacity":
                    //change the opacity for different browsers
                    object.opacity = (value/100);
                    object.MozOpacity = (value/100);
                    object.KhtmlOpacity = (value/100);
                    object.MsFilter = "progid:DXImageTransform.Microsoft.Alpha(Opacity="+value+")";
                    object.filter = "alpha(opacity="+value+")";
                    break;
                case "height":
                case "width":
                    object[styleProperty] = value+'px';
                    break;
                case "height top":
                case "width left":
                    styleProperties = styleProperty.split(' ');
                    var inc = Math.round((parseInt(object[styleProperties[0]]) - value)/2);
                    object[styleProperties[0]] = value+'px';
                    object[styleProperties[1]] = (parseInt(object[styleProperties[1]])+inc)+'px';
                    break;
            }
            if (typeof followUpAction == 'function') followUpAction();
        };
    function Dimensions() {
        this.windowHeight =
            function () {
                if (document.documentElement && document.documentElement.clientHeight)
                    return document.documentElement.clientHeight; // IE6
                if (document.body)
                    return document.body.clientHeight; // IE other
                return window.innerHeight;
            };
        this.windowWidth =
            function () {
                if (document.documentElement && document.documentElement.clientWidth)
                    return document.documentElement.clientWidth; // IE6
                if (document.body)
                    return document.body.clientWidth; // IE other
                return window.innerWidth;
            };
        this.pageHeight =
            function () {
                var h = this.windowHeight(), sh;
                if (window.innerHeight && window.scrollMaxY)
                    sh = window.innerHeight + window.scrollMaxY;
                else if (document.body.scrollHeight > document.body.offsetHeight)
                    sh = document.body.scrollHeight;
                else
                    sh = document.body.offsetHeight;
                return sh < h?h:sh;
            }
        this.pageWidth =
            function () {
                var w = this.windowWidth();
                if (window.scrollMaxY)
                    return window.scrollMaxY < w?w:window.scrollMaxY;
                if (document.body.scrollHeight > document.body.offsetHeight)
                    return document.body.scrollWidth < w?w:document.body.scrollWidth;
                return document.body.offsetWidth < w?w:document.body.offsetWidth;
            }
        this.pageScrolledDown =
            function () {
                if (window.pageYOffset)
                    return window.pageYOffset;
                if ((document.documentElement && document.documentElement.scrollTop))
                    return document.documentElement.scrollTop;
                return document.body.scrollTop;
            };
        this.pageScrolledRight =
            function () {
                if (window.pageXOffset)
                    return window.pageXOffset;
                if ((document.documentElement && document.documentElement.scrollLeft))
                    return document.documentElement.scrollLeft;
                return document.body.scrollLeft;
            };
    }
    function init() {
        /* Create the following structure in the DOM to do the lightbox stuff
           <div id="lightbox">
                <div id="lightboxContainer">
                    <div id="lightboxContent">
                    </div>
                    <div id="lightboxControl">
                        <img src="js/closelabel.gif" alt="Close" onclick="mylightbox.close();"/>
                    </div>
                </div>
           </div>
           <div id="lightboxUnderlay"></div>
        */
        var lightboxObj = document.getElementById("lightbox");
        if (lightboxObj)
            return; // already done!
        lightboxObj = make("div",{id:"lightbox"},
                            [make("div",{id:"lightboxContainer"},
                                    [make("div",{id:"lightboxContent"}),
                                     make("div",{id:"lightboxControl",
                                                 alt:"Close"})])]);
        var lightboxUnderlayObj = make("div",{id:"lightboxUnderlay"});
        document.body.appendChild(lightboxObj);
        document.body.appendChild(lightboxUnderlayObj);
        var lightboxControl = document.getElementById("lightboxControl");
        if (lightboxControl) {
            if (document.addEventListener) {
                lightboxControl.addEventListener('click',
                    function () {
                        window.olsLightbox.close();
                    },false);
            }
            else {
                lightboxControl.attachEvent('onclick',
                    function () {
                        window.olsLightbox.close();
                    });
            }
        }

        function make(tagname, attributes, children) {
            if (arguments.length == 2 && (attributes instanceof Array || typeof attributes == "string")) {
                children = attributes;
                attributes = null;
            }
            var e = document.createElement(tagname);
            if (attributes) {
                for(var name in attributes) {
                    e.setAttribute(name, attributes[name]);
                }
            }
            if (children != null) {
                if (children instanceof Array) {  // If it really is an array
                    for(var i = 0; i < children.length; i++) { // Loop through kids
                        var child = children[i];
                        if (typeof child == "string")          // Handle text nodes
                            child = document.createTextNode(child);
                        e.appendChild(child);  // Assume anything else is a Node
                    }
                }
                else if (typeof children == "string") // Handle single text child
                    e.appendChild(document.createTextNode(children));
                else e.appendChild(children);         // Handle any other single child
            }
            return e; // Finally, return the element.
        }
    }
    function isIE6orLess() {
        var ua = window.navigator.userAgent;
        var msie = ua.indexOf("MSIE ");
        if (msie <= 0) return false;
        return parseInt(ua.substring(msie+5,ua.indexOf(".",msie))) < 7?true:false;
    }
}

function olsRunOnLoad(f) {
    if (olsRunOnLoad.loaded) f();    // If already loaded, just invoke f() now.
    else olsRunOnLoad.funcs.push(f); // Otherwise, store it for later
}

olsRunOnLoad.funcs = []; // The array of functions to call when the document loads
olsRunOnLoad.loaded = false; // The functions have not been run yet.

// Run all registered functions in the order in which they were registered.
// It is safe to call runOnLoad.run() more than once: invocations after the
// first do nothing. It is safe for an initialization function to call
// runOnLoad() to register another function.
olsRunOnLoad.run = function() {
    if (olsRunOnLoad.loaded) return;  // If we've already run, do nothing

    for(var i = 0; i < olsRunOnLoad.funcs.length; i++) {
        try { olsRunOnLoad.funcs[i](); }
        catch(e) { /* An exception in one function shouldn't stop the rest */ }
    }

    olsRunOnLoad.loaded = true; // Remember that we've already run once.
    delete olsRunOnLoad.funcs;  // But don't remember the functions themselves.
    delete olsRunOnLoad.run;    // And forget about this function too!
};

// Register runOnLoad.run() as the onload event handler for the window
if (window.addEventListener)
    window.addEventListener("load", olsRunOnLoad.run, false);
else if (window.attachEvent) window.attachEvent("onload", olsRunOnLoad.run);
else window.onload = olsRunOnLoad.run;

