var LoginLightbox = Class.create();

LoginLightbox.prototype = {
    options: {
        overlayOpacity: 0.8,   // controls transparency of shadow overlay
        animate: true,         // toggles resizing animations
        resizeSpeed: 7,        // controls the speed of the image resizing animations (1=slowest and 10=fastest)
        borderSize: 10
    },

    // initialize()
    // Constructor runs on completion of the DOM loading. Calls updateImageList and then
    // the function inserts html at the bottom of the page which is used to display the shadow 
    // overlay and the image container.
    //
    initialize: function(params) {
        Object.extend(this.options, params || {});
        this.animating = true;

        if (this.options.resizeSpeed > 10) this.options.resizeSpeed = 10;
        if (this.options.resizeSpeed < 1)  this.options.resizeSpeed = 1;

        this.resizeDuration = this.options.animate ? ((11 - this.options.resizeSpeed) * 0.15) : 0;
        this.overlayDuration = this.options.animate ? 0.2 : 0;  // shadow fade in/out duration

        // When Lightbox starts it will resize itself from 250 by 250 to the current image dimension.
        // If animations are turned off, it will be hidden as to prevent a flicker of a
        // white 250 by 250 box.
        var size = (this.options.animate ? 250 : 1) + 'px';
        
        this.pageScroll = document.viewport.getScrollOffsets();
        this.pageHeight = document.viewport.getHeight();

        $('overlay').hide().observe('click', (function() { this.end(); }).bind(this));
        $('notLoggedIn').hide().observe('click', (function(event) { if (event.element().id == 'lightbox') this.end(); }).bind(this));
        //$('vpLoginForm').setStyle({ width: size, height: size });
        $('loadingLink').observe('click', (function(event) { event.stop(); this.end(); }).bind(this));
        $('bottomNavClose').observe('click', (function(event) { event.stop(); this.end(); }).bind(this));

        var th = this;
        var ids = 
            'overlay notLoggedIn dataContainer data outerFormContainer formContainer vpLoginForm loading loadingLink bottomNav bottomNavClose';  
        $w(ids).each(function(id){ 
            th[id] = $(id); 
        });

        this.displayForm();
    },

    //
    // updateImageList()
    // Loops through anchor tags looking for 'lightbox' references and applies onclick
    // events to appropriate links. You can rerun after dynamically adding images w/ajax.
    //
    displayForm: function() {
        this.displayForm = Prototype.emptyFunction;
        document.observe('click', (function(event){
            var target = event.findElement('a[rel^=vp-login-lightbox]') || event.findElement('area[rel^=vp-login-lightbox]');
            if (target) {
                event.stop();
                this.start();
            }
        }).bind(this));
    },

    //
    //  start()
    //  Display overlay and lightbox. If image is part of a set, add siblings to imageArray.
    //
    start: function() {
        $$('select', 'object', 'embed').each(function(node){ node.style.visibility = 'hidden' });

        // stretch overlay to fill page and fade in
        var arrayPageSize = this.getPageSize();
        this.overlay.setStyle({ width: arrayPageSize[0] + 'px', height: arrayPageSize[1] + 'px' });
        
        new Effect.Appear(this.overlay, { duration: this.overlayDuration, from: 0.0, to: this.options.overlayOpacity });
        
//        // calculate top and left offset for the lightbox 
        var lightboxTop = this.pageScroll[1] + (this.pageHeight / 10);
        var lightboxLeft = this.pageScroll[0];
        this.notLoggedIn.setStyle({ top: lightboxTop + 'px', left: lightboxLeft + 'px' }).show();
        
        this.showContent();
    },

    //
    //  changeImage()
    //  Hide most elements and preload image in preparation for resizing image container.
    //
    showContent: function() {
    	
        // hide elements during transition
        if (this.options.animate) this.loading.show();
        //this.voLogin.hide();
        // HACK: Opera9 does not currently support scriptaculous opacity and appear fx
        this.dataContainer.setStyle({opacity: .0001});

        //alert('>>'+this.vpLoginForm.clientWidth);
        this.resizeFormContainer(this.vpLoginForm.offsetWidth,this.vpLoginForm.offsetHeight);
    },

    //
    //  resizeImageContainer()
    //
    resizeFormContainer: function(imgWidth, imgHeight) {
        // get current width and height
        var widthCurrent  = this.outerFormContainer.getWidth() || (this.options.animate ? 250 : 1);
        var heightCurrent = this.outerFormContainer.getHeight() || (this.options.animate ? 250 : 1);

        // get new width and height
        var widthNew  = (imgWidth  + this.options.borderSize * 2);
        var heightNew = (imgHeight + this.options.borderSize * 2);
        
        this.outerFormContainer.setStyle({ width: widthNew + 'px' });
        this.outerFormContainer.setStyle({ height: heightNew + 'px' });
        
        // if new and old image are same size and no scaling transition is necessary, 
        // do a quick pause to prevent image flicker.
        var timeout = 0;

        (function(){
            this.dataContainer.setStyle({ width: widthNew + 'px' });
            this.showImage();
        }).bind(this).delay(timeout / 1000);

        // On centre l'image verticalement
        var padTop = (heightNew - imgHeight) / 2;
        this.formContainer.setStyle({paddingTop: padTop + 'px '});
    },
    
    //
    //  showImage()
    //  Display image and begin preloading neighbors.
    //
    showImage: function(){
        this.loading.hide();
        new Effect.Appear(this.vpLoginForm, { 
            duration: this.resizeDuration, 
            queue: 'end', 
            afterFinish: (function(){ this.updateDetails(); }).bind(this) 
        });
    },

    //
    //  updateDetails()
    //  Display caption, image number, and bottom nav.
    //
    updateDetails: function() {

        new Effect.Parallel(
            [
                //new Effect.SlideDown(this.imageDataContainer, { sync: true, duration: this.resizeDuration, from: 1, to: 0 }), 
                new Effect.Appear(this.dataContainer, { sync: true, duration: this.resizeDuration }) 
            ], 
            { 
                duration: this.resizeDuration, 
                afterFinish: (function() {
                    // update overlay size and update nav
                    var arrayPageSize = this.getPageSize();
                    this.overlay.setStyle({ height: arrayPageSize[1] + 'px' });
                }).bind(this)
            } 
        );
    },

    //
    //  end()
    //
    end: function() {
        this.notLoggedIn.hide();
        new Effect.Fade(this.overlay, { duration: this.overlayDuration });
        $$('select', 'object', 'embed').each(function(node){ node.style.visibility = 'visible' });
    },

    //
    //  getPageSize()
    //
    getPageSize: function() {
            
         var xScroll, yScroll;
        
        if (window.innerHeight && window.scrollMaxY) {    
            xScroll = window.innerWidth + window.scrollMaxX;
            yScroll = window.innerHeight + window.scrollMaxY;
        } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
            xScroll = document.body.scrollWidth;
            yScroll = document.body.scrollHeight;
        } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
            xScroll = document.body.offsetWidth;
            yScroll = document.body.offsetHeight;
        }
        
        var windowWidth, windowHeight;
        
        if (self.innerHeight) {    // all except Explorer
            if(document.documentElement.clientWidth){
                windowWidth = document.documentElement.clientWidth; 
            } else {
                windowWidth = self.innerWidth;
            }
            windowHeight = self.innerHeight;
        } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
            windowWidth = document.documentElement.clientWidth;
            windowHeight = document.documentElement.clientHeight;
        } else if (document.body) { // other Explorers
            windowWidth = document.body.clientWidth;
            windowHeight = document.body.clientHeight;
        }    
        
        // for small pages with total height less then height of the viewport
        if(yScroll < windowHeight){
            pageHeight = windowHeight;
        } else { 
            pageHeight = yScroll;
        }
    
        // for small pages with total width less then width of the viewport
        if(xScroll < windowWidth){    
            pageWidth = xScroll;        
        } else {
            pageWidth = windowWidth;
        }

        return [pageWidth,pageHeight];
    }
}

var AlertLightbox = Class.create();

AlertLightbox.prototype = {
    options: {
        overlayOpacity: 0.8,   // controls transparency of shadow overlay
        animate: true,         // toggles resizing animations
        resizeSpeed: 7,        // controls the speed of the image resizing animations (1=slowest and 10=fastest)
        borderSize: 10
    },

    // initialize()
    // Constructor runs on completion of the DOM loading. Calls updateImageList and then
    // the function inserts html at the bottom of the page which is used to display the shadow 
    // overlay and the image container.
    //
    initialize: function(params) {
        Object.extend(this.options, params || {});
        this.animating = true;

        if (this.options.resizeSpeed > 10) this.options.resizeSpeed = 10;
        if (this.options.resizeSpeed < 1)  this.options.resizeSpeed = 1;

        this.resizeDuration = this.options.animate ? ((11 - this.options.resizeSpeed) * 0.15) : 0;
        this.overlayDuration = this.options.animate ? 0.2 : 0;  // shadow fade in/out duration

        // When Lightbox starts it will resize itself from 250 by 250 to the current image dimension.
        // If animations are turned off, it will be hidden as to prevent a flicker of a
        // white 250 by 250 box.
        var size = (this.options.animate ? 250 : 1) + 'px';
        
        this.pageScroll = document.viewport.getScrollOffsets();
        this.pageHeight = document.viewport.getHeight();

        $('overlay').hide().observe('click', (function() { this.end(); }).bind(this));
        $('getAlert').hide().observe('click', (function(event) { if (event.element().id == 'lightbox') this.end(); }).bind(this));
        $('alertLoadingLink').observe('click', (function(event) { event.stop(); this.end(); }).bind(this));
        $('alertBottomNavClose').observe('click', (function(event) { event.stop(); this.end(); }).bind(this));

        var th = this;
        var ids = 
            'overlay getAlert alertDataContainer alertData alertOuterFormContainer alertFormContainer vpAlertForm alertLoading alertLoadingLink alertBottomNav alertBottomNavClose';  
        $w(ids).each(function(id){ 
            th[id] = $(id); 
        });

        this.displayForm();
    },

    //
    // updateImageList()
    // Loops through anchor tags looking for 'lightbox' references and applies onclick
    // events to appropriate links. You can rerun after dynamically adding images w/ajax.
    //
    displayForm: function() {
        this.displayForm = Prototype.emptyFunction;
        document.observe('click', (function(event){
            var target = event.findElement('a[rel^=vp-login-lightbox]') || event.findElement('area[rel^=vp-login-lightbox]');
            if (target) {
                event.stop();
                this.start();
            }
        }).bind(this));
    },

    //
    //  start()
    //  Display overlay and lightbox. If image is part of a set, add siblings to imageArray.
    //
    start: function() {
        $$('select', 'object', 'embed').each(function(node){ node.style.visibility = 'hidden' });

        // stretch overlay to fill page and fade in
        var arrayPageSize = this.getPageSize();
        this.overlay.setStyle({ width: arrayPageSize[0] + 'px', height: arrayPageSize[1] + 'px' });
        
        new Effect.Appear(this.overlay, { duration: this.overlayDuration, from: 0.0, to: this.options.overlayOpacity });
        
//        // calculate top and left offset for the lightbox 
        var lightboxTop = this.pageScroll[1] + (this.pageHeight / 10);
        var lightboxLeft = this.pageScroll[0];
        this.getAlert.setStyle({ top: lightboxTop + 'px', left: lightboxLeft + 'px' }).show();
        
        this.showContent();
    },

    //
    //  changeImage()
    //  Hide most elements and preload image in preparation for resizing image container.
    //
    showContent: function() {
    	
        // hide elements during transition
        if (this.options.animate) this.alertLoading.show();
        //this.voLogin.hide();
        // HACK: Opera9 does not currently support scriptaculous opacity and appear fx
        this.alertDataContainer.setStyle({opacity: .0001});

        //alert('>>'+this.vpLoginForm.clientWidth);
        this.resizeFormContainer(this.vpAlertForm.offsetWidth,this.vpAlertForm.offsetHeight);
    },

    //
    //  resizeImageContainer()
    //
    resizeFormContainer: function(imgWidth, imgHeight) {
        // get current width and height
        var widthCurrent  = this.alertOuterFormContainer.getWidth() || (this.options.animate ? 250 : 1);
        var heightCurrent = this.alertOuterFormContainer.getHeight() || (this.options.animate ? 250 : 1);

        // get new width and height
        var widthNew  = (imgWidth  + this.options.borderSize * 2);
        var heightNew = (imgHeight + this.options.borderSize * 2);
        
        this.alertOuterFormContainer.setStyle({ width: widthNew + 'px' });
        this.alertOuterFormContainer.setStyle({ height: heightNew + 'px' });

        
        // if new and old image are same size and no scaling transition is necessary, 
        // do a quick pause to prevent image flicker.
        var timeout = 0;

        (function(){
            this.alertDataContainer.setStyle({ width: widthNew + 'px' });
            this.showImage();
        }).bind(this).delay(timeout / 1000);

        // On centre l'image verticalement
        var padTop = (heightNew - imgHeight) / 2;
        this.alertFormContainer.setStyle({paddingTop: padTop + 'px '});
    },

    //
    //  showImage()
    //  Display image and begin preloading neighbors.
    //
    showImage: function(){
        this.alertLoading.hide();
        new Effect.Appear(this.vpAlertForm, { 
            duration: this.resizeDuration, 
            queue: 'end', 
            afterFinish: (function(){ this.updateDetails(); }).bind(this) 
        });
    },

    //
    //  updateDetails()
    //  Display caption, image number, and bottom nav.
    //
    updateDetails: function() {

        new Effect.Parallel(
            [
                //new Effect.SlideDown(this.imageDataContainer, { sync: true, duration: this.resizeDuration, from: 1, to: 0 }), 
                new Effect.Appear(this.alertDataContainer, { sync: true, duration: this.resizeDuration }) 
            ], 
            { 
                duration: this.resizeDuration, 
                afterFinish: (function() {
                    // update overlay size and update nav
                    var arrayPageSize = this.getPageSize();
                    this.overlay.setStyle({ height: arrayPageSize[1] + 'px' });
                }).bind(this)
            } 
        );
    },

    //
    //  end()
    //
    end: function() {
        this.getAlert.hide();
        new Effect.Fade(this.overlay, { duration: this.overlayDuration });
        $$('select', 'object', 'embed').each(function(node){ node.style.visibility = 'visible' });
    },

    //
    //  getPageSize()
    //
    getPageSize: function() {
            
         var xScroll, yScroll;
        
        if (window.innerHeight && window.scrollMaxY) {    
            xScroll = window.innerWidth + window.scrollMaxX;
            yScroll = window.innerHeight + window.scrollMaxY;
        } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
            xScroll = document.body.scrollWidth;
            yScroll = document.body.scrollHeight;
        } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
            xScroll = document.body.offsetWidth;
            yScroll = document.body.offsetHeight;
        }
        
        var windowWidth, windowHeight;
        
        if (self.innerHeight) {    // all except Explorer
            if(document.documentElement.clientWidth){
                windowWidth = document.documentElement.clientWidth; 
            } else {
                windowWidth = self.innerWidth;
            }
            windowHeight = self.innerHeight;
        } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
            windowWidth = document.documentElement.clientWidth;
            windowHeight = document.documentElement.clientHeight;
        } else if (document.body) { // other Explorers
            windowWidth = document.body.clientWidth;
            windowHeight = document.body.clientHeight;
        }    
        
        // for small pages with total height less then height of the viewport
        if(yScroll < windowHeight){
            pageHeight = windowHeight;
        } else { 
            pageHeight = yScroll;
        }
    
        // for small pages with total width less then width of the viewport
        if(xScroll < windowWidth){    
            pageWidth = xScroll;        
        } else {
            pageWidth = windowWidth;
        }

        return [pageWidth,pageHeight];
    }
}
