/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Cornelius Weiss <c.weiss@metaways.de>
 * @copyright   Copyright (c) 2007-2008 Metaways Infosystems GmbH (http://www.metaways.de)
 * @version     $Id:  $
 *
 */
 
Ext.namespace('Ext.ux');

/**
 * @class Ext.ux.SpaceGallery
 * @constructor
 */
Ext.ux.SpaceGallery = function(config) {
    Ext.apply(this, config);
    Ext.ux.SpaceGallery.superclass.constructor.call(this);
}


Ext.extend(Ext.ux.SpaceGallery, Ext.BoxComponent, {
    /**
     * @cfg {Object} perspective referenced from top and center of the first image in px
     */
    perspective: {
        horizontal : 60,
        vertical   : 0 // not supported yet
    },
    /**
     * @cfg {Float} multiplicator of imageSize.width for width of the bottom image
     * This determines the maxDepth
     */
    minScale: 0.4,
    /**
     * @cfg {Object} width, heigt. If provided, images containers could be aranged
     * before first image is loaded
     */
    imageSize: {},
    /**
     * holds imageEl of each image
     * @private
     */
    imageEls: [],
    /**
     * holds calculated perspective data
     * @private
     */
    perspectiveData: [],
    /**
     * @private
     */
    initComponent: function() {
        Ext.ux.SpaceGallery.superclass.initComponent.call(this);
    },
    /**
     * @private
     */
    onRender: function(ct, position) {
        var imageEl;
        
        Ext.ux.SpaceGallery.superclass.onRender.call(this, ct, position);
        if(!this.el) {
            var cfg = this.getAutoCreate();
            this.el = ct.createChild(cfg, position);
        }
        
        for(var i=0; i<this.pictures.length; i++) {
            imageEl = Ext.DomHelper.insertFirst(this.el, {tag: 'img', src: this.pictures[i].src}, true);
            this.imageEls.push(imageEl);
            
            // if imageSize is set, we could already applied perspetives before images are loaded
            if (this.imageSize.length == 2) {
                this.applyPerspective();
            } else if (i === 0) {
                this.imageSize = {};
                imageEl.on('load', function(e, dom) {
                    this.imageSize = Ext.get(dom).getSize();
                    this.applyPerspective()
                }, this);
            }
            imageEl.on('click', this.onImageClick, this);
        }
    },
    /**
     * executed when an image gets clicked
     * @private
     */
    onImageClick: function(e, dom) {
        this.imageEls[0].shift(this.fadeOutPerspectiveData);
        for(var n=1; n<this.imageEls.length; n++) {
            this.imageEls[n].shift(this.perspectiveData[n-1]);
        }
        this.cycleStack();
    },
    /**
     * cycles first image to last position in stack
     * @prvate
     */
    cycleStack: function() {
        var frontImageEl = this.imageEls.shift();
        this.imageEls.push(frontImageEl);
        this.applyPerspective.defer(600, this);
    },
    /**
     * applies perspective to each imageEl
     */
    applyPerspective: function() {
        if (this.perspectiveData.length != this.imageEls.length) {
            this.calculatePerspective();
        }
        
        var c;
        for(var n=0; n<this.imageEls.length; n++) {
            c = this.perspectiveData[n];
            this.imageEls[n].setSize(c.width, c.height);
            this.imageEls[n].setLeftTop(c.x, c.y);
            this.imageEls[n].setStyle({'z-index': this.imageEls.length - n + 1000});
            this.imageEls[n].setVisible(true);
            this.imageEls[n].setOpacity(c.opacity+0.1);
        }
    },
    /**
     * calculates perspective datas
     * 
     * @private
     */
    calculatePerspective: function() {
        var rad,  scale;
        var N = this.imageEls.length;
        var xOffset = this.imageSize.width/2;
        
        for(var n=0; n<N; n++) {
            rad = n/(N-1) * (Math.PI/2);
            scale = 1 - ( n/(N-1) *(1-this.minScale));
            this.perspectiveData.push({
                y: this.perspective.horizontal * ( 1- Math.sqrt(n/(N-1)) ),
                x: xOffset + (this.imageSize.width - scale * this.imageSize.width)/2,
                width: scale * this.imageSize.width,
                height: scale * this.imageSize.height,
                opacity: ( 1- Math.sqrt(n/(N-1)) ) //(1 - n/(N-1))
            });
        }
        
        this.fadeOutPerspectiveData = {
            width: 2 * this.imageSize.width,
            height: 2 * this.imageSize.height,
            y: this.perspective.horizontal * 2,
            x: xOffset + (-1) * (this.imageSize.width/2),
            opacity: 0
        };
    }
});

