﻿/// <reference name="MicrosoftAjax.js"/>

Type.registerNamespace("EntityLibrary.Web.WebControls");

EntityLibrary.Web.WebControls.WebGallery = function(element) {
    EntityLibrary.Web.WebControls.WebGallery.initializeBase(this, [element]);

    // Fields
    this._items = new Array();
    this._isVisible = false;
    this._isLoading = false;
    this._currentIndex = -1;
    this._preloader = null;
    this._previousData = null;
    this._nextData = null;
    this._shouldShowButtons = false;

    this._galleryCssClass = null;
    this._loadingImage = null;
    this._closeImage = null;
    this._previousImage = null;
    this._nextImage = null;

    this._overlay = null;
    this._container = null;
    this._dataContainer = null;
    this._loadingContainer = null;
    this._closeButtonContainer = null;
    this._previousButtonContainer = null;
    this._nextButtonContainer = null;

    // Handlers
    this._elementClickedHandler = null;
    this._keyDownHandler = null;
    this._windowResizedHandler = null;
    this._contentLoadedHandler = null;
    this._containerResizedHandler = null;
}

EntityLibrary.Web.WebControls.WebGallery.prototype = {
    initialize: function() {
        EntityLibrary.Web.WebControls.WebGallery.callBaseMethod(this, 'initialize');

        this._elementClickedHandler = Function.createDelegate(this, this.onElementClicked);
        this._keyDownHandler = Function.createDelegate(this, this.onKeyDown);
        this._windowResizedHandler = Function.createDelegate(this, this.onWindowResized);
        this._contentLoadedHandler = Function.createDelegate(this, this.onContentLoaded);
        this._containerResizedHandler = Function.createDelegate(this, this.onContainerResized);

        var overlay = document.createElement("div");
        overlay.id = this.get_id() + "__o";
        document.body.appendChild(overlay);
        $addHandler(overlay, "click", Function.createDelegate(this, this.onOverlayClicked));
        this._overlay = $("#" + overlay.id);

        var container = document.createElement("div");
        container.id = this.get_id() + "__c";
        document.body.appendChild(container);
        $addHandler(container, "mouseover", Function.createDelegate(this, this.onMouseOverContainer));
        $addHandler(container, "mouseout", Function.createDelegate(this, this.onMouseOutContainer));
        this._container = $("#" + container.id);

        this._overlay.css({
            position: 'absolute',
            backgroundColor: '#000000',
            opacity: 0.8,
            top: '0px',
            left: '0px',
            display: 'none',
            'z-index': 900
        });

        this._container.css({
            position: 'absolute',
            backgroundColor: '#FFFFFF',
            display: 'none',
            'z-index': 901
        });

        var baseId = this.get_id();
        this._container.append("<div id='" + baseId + "__c__l'><img src='" + this.get_loadingImage() + "' border='0' /></div>");
        this._container.append("<div id='" + baseId + "__c__d'><img border='0' /></div>");
        this._container.append("<div id='" + baseId + "__c__bc'><img src='" + this.get_closeImage() + "' border='0' alt='Fermer' /></div>");
        this._container.append("<div id='" + baseId + "__c__bp'><img src='" + this.get_previousImage() + "' border='0' alt='Image précédante' /></div>");
        this._container.append("<div id='" + baseId + "__c__bn'><img src='" + this.get_nextImage() + "' border='0' alt='Image suivante' /></div>");


        this._loadingContainer = $("#" + baseId + "__c__l");
        this._loadingContainer.css({
            position: 'absolute',
            top: '0px',
            left: '0px',
            display: 'none'
        });

        this._dataContainer = $("#" + baseId + "__c__d");
        this._dataContainer.css({
            padding: '10px'
        });

        this._closeButtonContainer = $("#" + baseId + "__c__bc");
        this._closeButtonContainer.css({
            position: 'absolute',
            top: '0px',
            left: '0px',
            'margin-left': '0px',
            'margin-top': '0px',
            cursor: 'pointer',
            diplay: 'none',
            'z-index': 1100
        });

        this._previousButtonContainer = $("#" + baseId + "__c__bp");
        this._previousButtonContainer.css({
            position: 'absolute',
            top: '90px',
            left: '0px',
            display: 'none',
            cursor: 'pointer',
            'z-index': 1000
        });

        this._nextButtonContainer = $("#" + baseId + "__c__bn");
        this._nextButtonContainer.css({
            position: 'absolute',
            top: '90px',
            right: '0px',
            display: 'none',
            cursor: 'pointer',
            'z-index': 1000
        });

        $addHandler(this._closeButtonContainer.get(0), "click", Function.createDelegate(this, this.hide));
        $addHandler(this._previousButtonContainer.get(0), "click", Function.createDelegate(this, this.previous));
        $addHandler(this._nextButtonContainer.get(0), "click", Function.createDelegate(this, this.next));

        var objs = $("." + this.get_galleryCssClass());
        for (var i = 0; i < objs.length; i++) {
            this._items.push(objs[i]);
            $addHandler(objs[i], "click", this._elementClickedHandler);
        }
    },

    dispose: function() {
        EntityLibrary.Web.WebControls.WebGallery.callBaseMethod(this, 'dispose');
    },

    get_galleryCssClass: function() {
        return this._galleryCssClass;
    },
    set_galleryCssClass: function(val) {
        this._galleryCssClass = val;
    },
    get_loadingImage: function() {
        return this._loadingImage;
    },
    set_loadingImage: function(val) {
        this._loadingImage = val;
    },
    get_closeImage: function() {
        return this._closeImage;
    },
    set_closeImage: function(val) {
        this._closeImage = val;
    },
    get_previousImage: function() {
        return this._previousImage;
    },
    set_previousImage: function(val) {
        this._previousImage = val;
    },
    get_nextImage: function() {
        return this._nextImage;
    },
    set_nextImage: function(val) {
        this._nextImage = val;
    },

    show: function() {
        if (this._isVisible)
            return;

        $addHandler(document, "keydown", this._keyDownHandler);
        $addHandler(window, "resize", this._windowResizedHandler);

        this._isVisible = true;

        var bounds = this._getViewBounds();

        this._overlay.css({
            width: bounds.totalWidth,
            height: bounds.totalHeight
        });

        this._container.css({
            top: Math.max((bounds.visibleHeight - this._container.height()) / 2, 0) + bounds.scrollTop,
            left: Math.max((bounds.visibleWidth - this._container.width()) / 2, 0) + bounds.scrollLeft
        });

        this._overlay.fadeIn('fast');
        this._container.fadeIn('fast');
    },

    hideX: function(e) {
        alert('xx');
    },

    hide: function() {
        if (!this._isVisible)
            return;

        $removeHandler(document, "keydown", this._keyDownHandler);
        $removeHandler(window, "resize", this._windowResizedHandler);

        this._currentIndex = -1;
        this._isVisible = false;

        this._container.fadeOut('fast');
        this._overlay.fadeOut('fast');
    },

    previous: function() {
        if (this._items.length > 1) {
            if (this._currentIndex > 0)
                this.displayElement(this._currentIndex - 1);
            else
                this.displayElement(this._items.length - 1);
        }
    },

    next: function() {
        if (this._items.length > 1) {
            if (this._currentIndex < this._items.length - 1)
                this.displayElement(this._currentIndex + 1);
            else
                this.displayElement(0);
        }
    },

    displayElement: function(idx) {
        if (idx < 0 || idx > this._items.length - 1)
            return;

        this._isLoading = true;
        this._currentIndex = idx;

        this.show();
        this._hideButtons();
        this._showLoading();

        this._preloader = new Image();
        $addHandler(this._preloader, "load", this._contentLoadedHandler);
        this._preloader.src = this._items[idx].href;
        
        this._preloadConcurrentElements();
    },

    update: function() {
        var bounds = this._getViewBounds();
        var img = this._dataContainer.children("img");

        var margin = 50;
        var padding = 20;

        var w = this._preloader.width;
        var h = this._preloader.height;

        if (bounds.visibleWidth < w + margin + padding || bounds.visibleHeight < h + margin + padding) {
            var ratio = this._preloader.width / this._preloader.height;
            var targetRatio = (bounds.visibleWidth - margin - padding) / (bounds.visibleHeight - margin - padding);

            if (targetRatio > ratio) {
                h = bounds.visibleHeight - margin - padding;
                w = h * ratio;
            }
            else {
                w = bounds.visibleWidth - margin - padding;
                h = w / ratio;
            }
        }

        img.attr('src', this._preloader.src);
        img.css({
            width: w,
            height: h
        });

        var left = Math.max(Math.ceil((bounds.visibleWidth - w - padding) / 2), 0);
        var top = Math.max(Math.ceil((bounds.visibleHeight - h - padding) / 2), 0);

        this._container.animate({
            top: top + bounds.scrollTop,
            left: left + bounds.scrollLeft,
            height: h + padding,
            width: w + padding
        }, null, null, this._containerResizedHandler);

        this._loadingContainer.animate({
            top: Math.max(Math.ceil((h + padding - this._loadingContainer.height()) / 2), 0),
            left: Math.max(Math.ceil((w + padding - this._loadingContainer.width()) / 2), 0)
        }, null, null, null);
    },

    onContentLoaded: function(e) {
        $removeHandler(this._preloader, "load", this._contentLoadedHandler);
        this.update();
    },

    onContainerResized: function(e) {
        this._loadingContainer.hide();
        this._dataContainer.show();
        this._isLoading = false;
        if (this._shouldShowButtons)
            this._showButtons();
    },

    onElementClicked: function(e) {
        var elmt = e.target;
        if (elmt.tagName == "IMG")
            elmt = elmt.parentNode;

        var idx = Array.indexOf(this._items, elmt);

        this.displayElement(idx);
        e.rawEvent.preventDefault ? e.rawEvent.preventDefault() : e.rawEvent.returnValue = false; 
    },

    onOverlayClicked: function(e) {
        this.hide();
    },

    onMouseOverContainer: function(e) {
        this._shouldShowButtons = true;
        if (!this._isLoading)
            this._showButtons();
    },

    onMouseOutContainer: function(e) {
        this._shouldShowButtons = false;
        this._hideButtons();
    },

    onKeyDown: function(e) {
        var escapeKey = 27;

        if (e.keyCode == escapeKey) {
            this.hide();
            e.rawEvent.preventDefault ? e.rawEvent.preventDefault() : e.rawEvent.returnValue = false; 
        }
        else if (e.keyCode == 37) {
            this.previous();
            e.rawEvent.preventDefault ? e.rawEvent.preventDefault() : e.rawEvent.returnValue = false; 
        }
        else if (e.keyCode == 39) {
            this.next();
            e.rawEvent.preventDefault ? e.rawEvent.preventDefault() : e.rawEvent.returnValue = false; 
        }
    },

    onWindowResized: function(e) {
        var bounds = this._getViewBounds();

        this._overlay.css({
            width: bounds.totalWidth,
            height: bounds.totalHeight
        });


        this._container.css({
            top: Math.max((bounds.visibleHeight - this._container.height()) / 2, 0) + bounds.scrollTop,
            left: Math.max((bounds.visibleWidth - this._container.width()) / 2, 0) + bounds.scrollLeft
        });
    },

    _showLoading: function() {
        var bounds = this._getViewBounds();

        this._loadingContainer.css({
            top: Math.max((this._container.height() - this._loadingContainer.height()) / 2, 0),
            left: Math.max((this._container.width() - this._loadingContainer.width()) / 2, 0)
        });

        this._dataContainer.hide();
        this._loadingContainer.show();
    },

    _showButtons: function() {
        this._closeButtonContainer.show();

        if (this._items.length > 1) {
            this._previousButtonContainer.show();
            this._nextButtonContainer.show();
        }
    },

    _hideButtons: function() {
        this._closeButtonContainer.hide();
        this._previousButtonContainer.hide();
        this._nextButtonContainer.hide();
    },

    _preloadConcurrentElements: function() {
        if (this._currentIndex > 0) {
            this._previousData = new Image();
            this._previousData.src = this._items[this._currentIndex - 1].href;
        }
        if (this._currentIndex < this._items.length - 1) {
            this._nextData = new Image();
            this._nextData.src = this._items[this._currentIndex + 1].href;
        }
    },

    _getViewBounds: 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 = windowWidth;
        } else {
            pageWidth = xScroll;
        }

        // scroll
        var leftScroll = 0, topScroll = 0;
        if (typeof (window.pageYOffset) == 'number') {
            //Netscape compliant
            topScroll = window.pageYOffset;
            leftScroll = window.pageXOffset;
        } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
            //DOM compliant
            topScroll = document.body.scrollTop;
            leftScroll = document.body.scrollLeft;
        } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
            //IE6 standards compliant mode
            topScroll = document.documentElement.scrollTop;
            leftScroll = document.documentElement.scrollLeft;
        }

        return {
            visibleWidth: windowWidth, visibleHeight: windowHeight,
            totalWidth: pageWidth, totalHeight: pageHeight,
            scrollTop: topScroll, scrollLeft: leftScroll
        };
    }
}
EntityLibrary.Web.WebControls.WebGallery.registerClass('EntityLibrary.Web.WebControls.WebGallery', Sys.UI.Control);
if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();