/*
    Disclaimer

    While we make every effort to ensure that this code is fit for its intended
    purpose, we make no guarantees as to its functionality. CoreTrek AS will
    accept no responsibility for the loss of data or any other damage or
    financial loss caused by use of this code.


    Copyright

    This programming code is copyright of CoreTrek AS. Permission to run this
    code is given to approved users of CoreTrek's publishing system CorePublish.

    This source code may not be copied, modified or otherwise repurposed for use
    by a third party without the written permission of CoreTrek AS.

    Contact webmaster@coretrek.com for information.

    ============================================================================
    IMPORTANT! This javascript is dependent on Prototype.
    ============================================================================

    SiteComponents Lightbox

    Displays a given URL or HTML snippet in a modal layer. All anchor tags that
    is set with the css-class "lightbox" will be opened in a lightbox. Just
    include this js-file, or the compressed lib.js, to enable.

    * Important SiteComponents requirements: *

      - Kjapp lightbox style definitions
      - File html/images/lightbox/ff-overlay-img.png
      - File html/history-frame.php
      - Also remember to set the html/body height to 100% in your CSS

    If you want to programmatically open a lightbox, this can be done using
    the lightbox objects show or showHtml methods like this:

    lightbox.show('http://coretrek.no/cms/corepublish/webpublisering/');

    lightbox.showHtml("<h1>I'm in a lightbox!</h1>");

*/


// ----------------------------------------------------------------------------

var Lightbox = Class.create({

    // =====  PUBLIC METHODS  =================================================

    /**
     * Use this method to display a given HTML snippet inside a lightbox.
     * If you have a regular HTML (prototype) element, use it's innerHTML
     * property to get the HTML to display.
     */
    showHtml: function(html) {
        this.showLoadingState();
        this.content.update(html);
        this.doShow();
    },

    /**
     * Use this if the content to be displayed inside the lightbox is avaliable
     * at an URL. All content from the URL will be fetched using Ajax and
     * inserted into the lightbox.
     *
     * Please note that because of Ajax limitations, the URL must be on the
     * same host as the rest of the site.
     *
     * A.lightbox links is rewritten to call this function with the href
     * property as contentUrl.
     */
    show: function(contentUrl) {
        lightbox.getAndShowContentFromUrl(contentUrl);
    },

    /**
     * Use this to hide an open lightbox.
     */
    hide: function() {
        lightbox.historyPolling.stop();

        // Re-enable window scrollbars for IE6
        if(this.isIE6()) {
            window.scrollTo(this.scolloffset[0], this.scolloffset[1]);
        }
        document.getElementsByTagName('html').item(0).style.overflow = 'auto';

        this.lightbox.hide();
        this.content.hide();
        this.overlay.hide();

        this.showPersistentObjects(true);

        this.content.update(" ");

        if(window.location.hash == "#modal") {
            history.back(1);
        }
    },

    /**
     * This function initializes all a.lightbox links and add the
     * lightbox.show() method as the click action.
     */
    load: function() {
        $$('a.lightbox').each(function (element) {
            element.observe('click', function (event) {
                event.stop();

                var element = Event.findElement(event, 'a');
                if(element != document) {
                    lightbox.show(element.getAttribute('href'));
                }
            });
        });
    },

    /**
     * Used to check if the lightbox is visible.
     */
    isVisible: function() {
       return $('lightbox').visible;
    },

    /**
     * Constructor used to insert the lightbox HTML into the document.
     */
    initialize: function() {
        this.history = new Object();

	    var objBody = document.getElementsByTagName('body').item(0);

        if(Prototype.Browser.IE) {
            var objHistoryFrame = document.createElement('iframe');
            objHistoryFrame.setAttribute('id', 'lightbox-history-frame');
            objHistoryFrame.style.display = 'block';
            objHistoryFrame.style.visibility = 'hidden';
            objHistoryFrame.src = "/history-frame.php";
            objHistoryFrame.style.position = 'absolute';
            objHistoryFrame.style.top = '0';
            objHistoryFrame.style.left = '0';
            objHistoryFrame.style.width = '1px';
            objHistoryFrame.style.height = '1px';
            objBody.appendChild(objHistoryFrame);
            this.historyFrame = objHistoryFrame;
        }

	    // Add the lightbox html structure to end of page
	    var objLightbox = document.createElement('div');
	    objLightbox.setAttribute('id', 'lightbox');
	    objLightbox.style.display = 'none';
	    objBody.appendChild(objLightbox);

	    var objOverlay = document.createElement('div');
	    objOverlay.setAttribute('id', 'lightbox-overlay');
	    objOverlay.style.display = 'none';
	    objLightbox.appendChild(objOverlay);

	    var objContainer = document.createElement('div');
	    objContainer.setAttribute('id', 'lightbox-container');
	    objLightbox.appendChild(objContainer);

	    var objCloseButtonContainer = document.createElement('div');
	    objCloseButtonContainer.setAttribute('id', 'lightbox-close-container');
	    objContainer.appendChild(objCloseButtonContainer);

	    var objCloseButton = document.createElement('a');
	    objCloseButton.setAttribute('id', 'lightbox-close');
	    objCloseButton.setAttribute('href', '#');

	    var objCloseButtonSpan = document.createElement('span');
	    objCloseButton.appendChild(objCloseButtonSpan);

	    var objCloseText = document.createTextNode("Close");
	    objCloseButtonSpan.appendChild(objCloseText);
	    objCloseButtonContainer.appendChild(objCloseButton);

	    var objStart = document.createElement('div');
	    objStart.setAttribute('id', 'lightbox-start');
	    objContainer.appendChild(objStart);

	    var objSpinner = document.createElement('div');
	    objSpinner.setAttribute('id', 'lightbox-spinner');
	    objContainer.appendChild(objSpinner);

	    var objContent = document.createElement('div');
	    objContent.setAttribute('id', 'lightbox-content');
	    objContent.style.display = 'none';
	    objContainer.appendChild(objContent);

	    var objEnd = document.createElement('div');
	    objEnd.setAttribute('id', 'lightbox-end');
	    objContainer.appendChild(objEnd);

		objLightbox.appendChild(objContainer);

        this.content = $('lightbox-content');
        this.lightbox = $('lightbox');
        this.overlay = $('lightbox-overlay');
        this.close = $('lightbox-close');

		this.close.observe('click', function(event) {
            event.stop();
            lightbox.hide();
        });

        this.overlay.observe('click', function(event) {
            event.stop();
            lightbox.hide();
        });

		// Set opacity on overlay layer. Because of a bug in Firefox, causing
		// fixed positioned layers (behind a flash) to render the flash
		// invisible. This has to be done with a semitransparent png on this
		// browser. Make sure that the png has the same design as the css
		// styled overlay layer has on the other browsers.
        if(Prototype.Browser.Gecko) {
            this.overlay.setStyle({
                background: 'url(/images/lightbox/ff-overlay-img.png)'
            });
        } else {
            this.overlay.setStyle({
                opacity: 0.8
            });
        }
	},


    // =====  PRIVATE METHODS  ================================================

	prepareHistory: function() {
        if(Prototype.Browser.IE) {
            lightbox.historyFrame.src = "/history-frame.php?modal";
        } else {
            window.location.hash = "#modal";
        }

	    lightbox.historyPolling = new PeriodicalExecuter(function(pe) {
	        var close = false;
	        if(Prototype.Browser.IE) {
	            var frameTitle = lightbox.historyFrame.contentWindow.document.title;
	            if(frameTitle.indexOf("?modal") < 0) {
	                close = true;
	            }
	        } else {
	            var hash = window.location.hash;
	            if(window.location.hash != "#modal") {
	                close = true;
	            }
	        }

	        if(close) {
	            pe.stop();
	            if(lightbox.isVisible()) {
	                lightbox.hide();
	            }
	        }
	    }, 1);
	},

    isIE6: function() {
        if(Prototype.Browser.IE && navigator.appVersion.match(/MSIE 6\.0/)) {
            return true;
        } else {
            return false;
        }
    },

	// In IE6/IE7 and Opera some items will always show on top of the lightbox.
	// This is a function used to hide these elements.
	showPersistentObjects: function(show) {
	    $$('select', 'embed', 'object').each(function(element) {
	        if(show) {
	            element.style.visibility = 'visible';
	        } else {
	            element.style.visibility = 'hidden';
	        }
	    });
	},

    showLoadingState: function() {
        this.prepareHistory();

        this.showPersistentObjects(false);
        $('lightbox-spinner').show();
        $('lightbox-overlay').show();
        $('lightbox').show();

        // Disable scrollbars for main window (and on IE6 scroll to top to
        // align the overlay correctly
        this.scolloffset = document.viewport.getScrollOffsets();
        document.getElementsByTagName('html').item(0).style.overflow = 'hidden';

        if(Prototype.Browser.IE && navigator.appVersion.match(/MSIE 6\.0/)) {
            window.scrollTo(0, 0);
        }

        this.loadingStarted = true;
    },

    doShow: function() {
        if(!this.loadingStarted) {
            this.showLoadingState();
        }
        $('lightbox-spinner').hide();
        $('lightbox-content').show();
    },

	// Private function! Must not be called manually.
	getAndShowContentFromUrl: function(contentUrl) {
        if(contentUrl == null) {
            alert("No URL provided");
            return;
        }

        this.showLoadingState();

        new Ajax.Request(contentUrl, {
            method: 'get',

            onSuccess: function(transport) {
                $('lightbox-content').update(transport.responseText);
                this.doShow();
            }.bind(this),

            onFailure: function(request) {
                this.hide();
                alert("Could not connect to URL");
            }.bind(this)
        });
	}

});
