﻿Atlantis_Web_UI_TileBrowser_Manager = new Class({

    Extends: Atlantis_Web_UI_Control_Base,

    _control: null,
    _tileContainer: null,
    _tilesDiv: null,
    _prevBtn: null,
    _nextBtn: null,
    _tiles: [],

    _tileWidth: null,
    _minSpacing: null,
    _tileSpacing: null,

    _periodicallyMove: null,
    _resizedDelay: null,
    _mouseIsOver: false,
    _dynamicHeight: true,
    _periodMoveMilli: 0,

    _position: 0,

    _doInit: function(config, partial) {

        if (partial) return; // we don't need to do anything on partial page loads

        this._control = $(this._id);
        this._tileContainer = this._control.getElement('.tile_container');
        this._tilesDiv = this._control.getElement('.tiles');

        this._control.getElements('.atl_tilebrowser_tile').each(function(tile) {
            this._tiles[this._tiles.length] = tile;
            tile.setStyle('position', 'absolute');
        } .bind(this));
        this._tileWidth = config.tileWidth;
        this._minSpacing = config.minSpacing;
        this._tileSpacing = this._minSpacing;
        this._dynamicHeight = config.dynamicHeight;
        this._periodMoveMilli = config.periodMoveIntervalMilli;

        // remove the scroll bar
        this._tileContainer.setStyle('overflow', 'hidden');

        this._prevBtn =
            new Element('div', { 'class': 'prev_btn' })
            .addEvent('click', this._prevClicked.bindWithEvent(this))
            .injectBefore(this._tileContainer);
        this._nextBtn =
            new Element('div', { 'class': 'next_btn' })
            .addEvent('click', this._nextClicked.bindWithEvent(this))
            .injectAfter(this._tileContainer);


        window.addEvent('resize', this._windowResized.bindWithEvent(this));
        this._control.addEvents({
            'mouseover': this._mouseOver.bind(this),
            'mouseout': this._mouseOut.bind(this)
        });

        this._reviewLayout(true);
        this._resetPeriodicalMove();
    },

    _resetPeriodicalMove: function() {
        if (this._periodicallyMove) $clear(this._periodicallyMove);
        if (this._periodMoveMilli > 0) {
            this._periodicallyMove = this._periodMove.periodical(this._periodMoveMilli, this);
        }
    },

    _mouseOver: function() {
        this._mouseIsOver = true;
    },

    _mouseOut: function() {
        this._mouseIsOver = false;
    },

    _periodMove: function() {
        if (!this._mouseIsOver) {
            this._position++;
            this._reviewLayout();
        }
    },

    _prevClicked: function(evt) {
        this._position--;
        this._reviewLayout(false, true, true);
        this._resetPeriodicalMove();
    },

    _nextClicked: function(evt) {
        this._position++;
        this._reviewLayout(false, true, true);
        this._resetPeriodicalMove();
    },

    _windowResized: function(evt) {
        if (this._resizedDelay) {
            $clear(this._resizedDelay);
            this._resizedDelay = null;
        }

        this._resizedDelay = this._reviewLayout.delay(500, this);
    },

    _reviewLayout: function(instant, fromClick) {
        if (this._dynamicHeight) {
            var h = this._getMaxTileHeight();
            this._tilesDiv.setStyle('height', h);
            this._nextBtn.setStyle('height', h);
            this._prevBtn.setStyle('height', h);
        }
        this._tileSpacing = this._calculateSpacingToFit();
        var positions = this._calculateTilePositions();
        this._moveTilesToPosition(positions, instant, fromClick);
    },

    _getMaxTilesOnPage: function() {
        return Math.max(1, Math.min(Math.floor(this._tileContainer.getWidth() / (this._tileWidth + this._minSpacing)), this._tiles.length));
    },

    _getVisibleTileCount: function() {
        return Math.floor(this._tileContainer.getWidth() / (this._tileWidth + this._tileSpacing));
    },

    _getMaxTileHeight: function() {
        var height = 0;
        this._tiles.each(function(tile, idx) {
            height = Math.max(height, tile.getHeight());
        } .bind(this));

        return height;
    },

    _calculateTilePositions: function() {

        var ret = [];

        //var relativePos = this._position % this._tiles.length;
        var visible = this._getVisibleTileCount();

        this._tiles.each(function(tile, idx) {

            var width = this._tileWidth + (this._tileSpacing / 2);

            var relative = ((this._tiles.length - (this._position % this._tiles.length)) + idx) % this._tiles.length;

            var left;
            var onEachSide = (this._tiles.length - visible) / 2;
            var wrapPoint = visible + onEachSide;

            //tile.getElement('.inner').set('html', idx + ', ' + relative);
            //this._nextBtn.set('html', this._position);
            //this._prevBtn.set('html', wrapPoint);

            if (relative < wrapPoint) {
                left = relative * width;
                left += (relative + 1) * (this._tileSpacing / 2);
            }
            else {
                var under = (relative - wrapPoint);
                left = -(this._tiles.length - relative) * (this._tileWidth + this._tileSpacing);
                left += (this._tileSpacing / 2);
            }

            ret[ret.length] = Math.floor(left);
        } .bind(this));

        return ret;
    },

    _calculateSpacingToFit: function() {

        var totalTileVisibleSpace = this._getMaxTilesOnPage() * this._tileWidth;
        var freeSpace = Math.max(0, (this._tileContainer.getWidth()) - totalTileVisibleSpace);
        var spacing = freeSpace / this._getMaxTilesOnPage();
        return spacing;
    },

    _moveEffects: [],
    _fadeMoveEffects: [],

    _stopAllEffects: function() {
        this._moveEffects.each(function(effect) {
            if (effect) effect.cancel();
        });
        this._fadeMoveEffects.each(function(effect) {
            if (effect) {
                effect.cancel();
                effect.clearChain();
            }
        });
    },

    _moveTilesToPosition: function(positions, instant, fromClick) {

        this._stopAllEffects();
        this._tiles.each(function(tile, idx) {

            var pos = tile.getPosition();
            var changePolarity = Math.abs(pos.x - positions[idx]) >= (this._tilesDiv.getSize().x / 2);
            var visible =
                ((pos.x >= 0) && (pos.x < this._tileContainer.getWidth())) ||
                ((positions[idx] >= 0) && (positions[idx] < this._tileContainer.getWidth()));

            if (instant || !visible) {
                tile.setStyles({
                    'left': positions[idx],
                    'opacity': 1
                });
            }
            else {
                if (changePolarity) {
                    this._fadeMoveEffects[idx] = new Fx.Tween(tile, { duration: 'short', property: 'opacity' }).chain(
                        function() { this.start(0); },
                        function() {
                            tile.setStyle('left', positions[idx]);
                            if (fromClick) {
                                this.start(1);
                            }
                            else {
                                this.start.delay(1000, this, 1);
                            }
                        }
                    );
                    this._fadeMoveEffects[idx].callChain();
                }
                else {
                    tile.setStyle('opacity', 1);

                    this._moveEffects[idx] = new Fx.Tween(tile, {
                        duration: fromClick ? 'long' : 2000,
                        property: 'left',
                        transition: fromClick ? 'back:out' : 'back:in:out'
                    });
                    this._moveEffects[idx].start(positions[idx]);
                }
            }

        } .bind(this));
    }


});

Atlantis_Web_UI_Control_Manager_Instance.register(
    'Atlantis_Web_UI_TileBrowser',
    'Atlantis_Web_UI_TileBrowser_Manager');
