/*
Lightbox.

[Description]
A simple "Lightbox" class built with jQuery. A lightbox provides a modal style 
window within a web browser.

[Version]
1.0

[Dependencies]
jquery.js (v1.2.6) {http://jquery.com}
jquery.dimensions.js (v1.2) {http://plugins.jquery.com/project/dimensions}

[Author]
Anthony Blackshaw <ant@getme.co.uk> (www.getme.co.uk)
Copyright (c)2008
*/

function Lightbox( on_init, on_show, on_hide, on_help ) {
    
    /*
    The "Lightbox" class.
    */
    
    var lightbox = this;
    
    this.size = [ 500, 300 ];
    this.title = "Lightbox";
    this.visible = null;

    // Callback functions
    this.on_init = on_init;
    this.on_show = on_show;
    this.on_hide = on_hide;
    this.on_help = on_help;
    
    // To set the interface up we load some HTML from a file, then call
    // "init_interface" to bind all events.
    
    // Setup a division to load the lightbox elements into
    $( "body" ).append( "<div id='lightbox'></div>" );
     
    // Load the HTML
    $( "#lightbox" ).load( "html/lightbox.html", function() { lightbox._init_interface(); } );
    
}

Lightbox.prototype._init_interface = function() {

    /*
    Initialise the various interface elements.
    */

    var lightbox = this;
    
    // Help option
    if ( this.on_help ) {
        $( "#lightbox-help" ).bind( "click", { "lightbox" : this }, this.on_help );
    } else {
        $( "#lightbox-help" ).css( { "display" : "none" } );
    }
    
    // Close option
    $( "#lightbox-close" ).bind( "click", 
        function( ev ) { lightbox.hide(); return false; }
        );
    
    // Support 'Esc' key close     
    $( document ).bind( "keydown",  function( ev ) { 
        if( ev.which == 27 ) {  
            lightbox.hide();
        } } );             
    
    // Make sure the lightbox is hidden
    this.set_visible( false, false, this.on_init );
}

Lightbox.prototype.set_visible = function( visible, tween, callback ) {

    /* 
    Set the visibility of the light box.
    */
    
    var lightbox = this;
    
    // Only act if visibility has changed 
    if ( this.visible != visible ) {
        
        // Update the lightbox's visibility
        if ( visible ) {
            
            // Show the lightbox
            this.visible = true;
            
            // Title
            $( "#lightbox-title" ).html( this.title );
            
            // Size
            var final_size = [this.size[0],this.size[1]];
            this.size = [200,200]
            $( "#lightbox-stage" ).css( { "width" : this.size[0], "height" : this.size[1] } );
            $( "#lightbox-shadow" ).css( { "width" : this.size[0], "height" : this.size[1] } );
            
            // Position
            var stage_x = ( $( window ).width() - $( "#lightbox-stage" ).width() ) / 2;
            var stage_y = ( $( window ).height() - $( "#lightbox-stage" ).height() ) / 2 + $( window ).scrollTop();
            $( "#lightbox-stage" ).css( { "top" : stage_y, "left" : stage_x } );
            $( "#lightbox-shadow" ).css( { "top" : stage_y, "left" : stage_x } );
            
            // Ensure the parent division is visible
            $( "#lightbox" ).css( "display", "block" );
            
            // Curtain
            $( "#lightbox-curtain" ).css( { "display" : "block", 
                "height" : $( document ).height()
                } );
            
            // IE fix for curtains width (100% is not calculated correctly during 
            // size transitions).
            if ( jQuery.browser.msie ) {
                $( "#lightbox-curtain" ).css( "width", $( window ).width() );
            }        
            
            if ( tween ) {
            
                // Stage
                $( "#lightbox-stage" ).fadeIn( "normal",
                    function() {
                        
                        // Size
                        lightbox.set_size( final_size, 
                            true, 
                            function() { 
                                
                                // Titlebar
                                $( "#lightbox-titlebar" ).fadeIn( "fast",
                                    function() {
                                        
                                        // Content
                                        $( "#lightbox-content" ).fadeIn( "normal",
                                            function() {
                                                if ( callback ) { 
                                                    callback.call( lightbox );
                                                } 
                                            } );
                                        
                                    } );                            
                            });

                    } );     
        
            } else {

                $( "#lightbox-curtain" ).css( "display", "show" );
                $( "#lightbox-stage" ).css( "display", "show" );
                $( "#lightbox-shadow" ).css( "display", "show" );
                $( "#lightbox-titlebar" ).css( "display", "show" );
                $( "#lightbox-content" ).css( "display", "show" );
                
                if ( callback ) { 
                    callback.call( this );
                }
            }
        
        } else {
        
            // Hide the lightbox
            if ( tween ) {
            
                // Hide title
                $( "#lightbox-content" ).fadeOut( "normal",
                    function() {
                        $( "#lightbox-titlebar" ).fadeOut( "fast", 
                            function() {
                                var final_size = lightbox.size;
                                lightbox.set_size( [200,200],
                                    true,
                                    function() {
                                        $( "#lightbox-shadow" ).css( "display", "none" );
                                        $( "#lightbox-stage" ).fadeOut( "normal",
                                            function() { 
                                                lightbox.size = final_size;
                                                $( "#lightbox-curtain" ).css( "display", "none" );
                                                lightbox.visible = false;
                                                if ( callback ) { 
                                                    callback.call( lightbox );
                                                }
                                            } );               
                                    } );
                            } );
                    } );    
            } else {
            
                $( "#lightbox-content" ).css( "display", "none" );
                $( "#lightbox-titlebar" ).css( "display", "none" );
                $( "#lightbox-stage" ).css( "display", "none" );
                $( "#lightbox-shadow" ).css( "display", "none" );
                $( "#lightbox-curtain" ).css( "display", "none" );
        
                lightbox.visible = false;
                
                if ( callback ) { 
                    callback.call( this );
                }
            }
        }
    } else {
        
        // No visibility change required
        if ( callback ) { 
            callback.call( this );
        }
    }
}

Lightbox.prototype.show = function( callback ) {
    
    /* 
    Show the lightbox.
    */ 
    
    callback = callback || this.on_show;
    this.set_visible( true, true, callback );
}

Lightbox.prototype.hide = function( callback ) {

    /*
    Hide the lightbox.
    */ 
    
    callback = callback || this.on_show;
    this.set_visible( false, true, callback );
}

Lightbox.prototype.toggle = function( callback ) {
    
    /* 
    Toggle the lightbox's visisbility.
    */ 
    
    this.set_visible( !this.visible, true, callback );
}

Lightbox.prototype.set_size = function( size, tween, callback ) {
    
    /* 
    Set the size of the lightbox.
    */
    
    var lightbox = this;
    
    if ( size[0] != this.size[0] || size[1] != this.size[1] ) {
        
        // Resize the lightbox
        this.size = size;
        
        // Ensure the curtain covers the whole screen
        $( "#lightbox-curtain" ).css( { "height" : $( document ).height() } );

        // IE fix for curtains width (100% is not calculated correctly during 
        // size transitions).
        if ( jQuery.browser.msie ) {
            $( "#lightbox-curtain" ).css( "width", $( window ).width() );
        }        
        
        // Position
        var stage_x = ( $( window ).width() - size[0] ) / 2;
        var stage_y = ( $( window ).height() - size[1] ) / 2 + $( window ).scrollTop();
            
        if ( tween && this.visible ) {
            
            // We use a custom event to handle the end of the resize animation            
            $( "#lightbox-shadow" ).css( "display", "none" );
            $( "#lightbox-stage" ).animate( { 
                "top" : stage_y,
                "left" : stage_x,
                "width" : size[0], 
                "height" : size[1] },
                function() { 
                    $( "#lightbox-shadow" ).css( { "width" : lightbox.size[0], "height" : lightbox.size[1] } );
                    $( "#lightbox-shadow" ).css( "display", "block" );
                    $( "#lightbox-shadow" ).css( { "top" : stage_y, "left" : stage_x } );
                    
                    if ( callback ) { 
                        callback.call( lightbox );
                    } 
                } );
                
        } else {
            $( "#lightbox-stage" ).css( { "width" : size[0], "height" : size[1] } );
            $( "#lightbox-shadow" ).css( { "width" : size[0], "height" : size[1] } );
            $( "#lightbox-stage" ).css( { "top" : stage_y, "left" : stage_x } );
            $( "#lightbox-shadow" ).css( { "top" : stage_y, "left" : stage_x } );
            
            if ( callback ) { 
                callback.call( this );
            }                    
        }
    } else { 
        
        // No size change required
        if ( callback ) { 
            callback.call( this );
        }        
    }
}

Lightbox.prototype.set_title = function( title, tween, callback ) {

    /*
    Set the title for the lightbox.
    */

    var lightbox = this;

    if ( title != this.title ) {
        
        // Change the title
        this.title = title;
        
        if ( tween && this.visible ) {
            $( "#lightbox-title" ).fadeOut( "fast",
                function() {
                    $( "#lightbox-title" ).html( lightbox.title );
                    $( "#lightbox-title" ).fadeIn( "fast",
                        function () {
                            if ( callback ) { 
                                callback.call( lightbox );
                            }     
                        } );
                } );
        } else {
            $( "#lightbox-title" ).html( this.title );
            if ( callback ) { 
                callback.call( this );
            } 
        }
        
    } else {
        
        // No title change required
        if ( callback ) { 
            callback.call( this );
        }        
    }
}