///-codeFile-//////////////////////////////////////////////////////////////////
// Carousel.js
//
// Written by Doug Greenall (douggreenall.co.uk)
// Copyright (c) 2008 Doug Greenall
//
// Feel free to use this code in any of your own personal projects but please
// leave this notice and my details intact. This code may not be used for any
// commercial projects without explicit permission
///////////////////////////////////////////////////////////////////////////////


///-class-/////////////////////////////////////////////////////////////////////
// CarouselItem
///////////////////////////////////////////////////////////////////////////////
function CarouselItem(Parent, HREF, ImageSRC, url, text) {
    ///-data-//////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////

    this._parent = Parent;
    this._ID = this._parent._ID + 'Item' + this._parent._items.length;

    this._href = HREF;
    this._element = null;
    this._elementt = null;
    this._url = url;
    this._text = text;

    this._position = new Vector2D(0, 0);
    this._size = this._parent._itemSize.Clone();

    this._image = new Image();
    this._image.src = ImageSRC;

    ///-methods-///////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////

    this.GetElement = function() {
        if (!this._element) {
            this._element = wGet(this._ID);
            this._elementt = wGet('tt' + this._ID);
        }

        return this._element;
    };

    this.GetMarkup = function() {
        var screenSize = this.GetScreenSize();
        var screenPosition = this.GetScreenPosition();

        return '<a href="' + this._url + '">\n' +
               '    <img id="' + this._ID + '" style="position:absolute; ' +
               'left:' + screenPosition.GetXPxl() + '; ' +
               'top:' + screenPosition.GetYPxl() + '; ' +
               'border:none; z-index:' + this.GetZIndex() + ';" ' +
               'src="' + this._image.src + '" ' +
               'width="' + screenSize.GetXInt() + '" ' +
               'height="' + screenSize.GetYInt() + '" ' +
               'alt="' + this._text + '" onmousedown="javascript:' + this._parent._ID + '.MouseDown(event);" />' +
               '<span id="tt' + this._ID + '" style="position: absolute; top:' + (screenPosition.GetYInt() + screenSize.GetYInt()) + 'px; left:' + screenPosition.GetXPxl() + '; z-index:' + (this.GetZIndex() + 1) + ';">' + this._text + '</span>' +
               '</a>\n';
    };

    this.GetScreenPosition = function() {
        var returnVal = this._parent._itemPosition.Clone();
        var offset = (this._parent._itemSize._x - this._size._x) / 2;

        returnVal._x += this._position._x * (returnVal._x + offset) + offset;
        returnVal._y += this._position._y * returnVal._y;

        return returnVal;
    };

    this.GetScreenSize = function() {
        this._size = this._parent._itemSize.Clone();

        this._size.MulVal((this._position._y + 1.5) / 2.5);

        return this._size;
    };

    this.GetZIndex = function() {
        return Math.round((this._position._y + 2) * 10000);
    };

    this.Update = function() {
        this._parent.Rotate(this._position);

        var screenSize = this.GetScreenSize();
        var screenPosition = this.GetScreenPosition();

        if (this.GetElement()) {
            this._element.style.left = screenPosition.GetXPxl();
            this._element.style.top = screenPosition.GetYPxl();
            this._element.width = screenSize.GetXInt();
            this._element.height = screenSize.GetYInt();

            this._element.style.zIndex = this.GetZIndex();

            this._elementt.style.left = screenPosition.GetXPxl();
            this._elementt.style.top = screenPosition.GetYInt() + screenSize.GetYInt() + 'px';
            this._elementt.style.zIndex = this.GetZIndex() + 1;
        }
    };
}


///-class-/////////////////////////////////////////////////////////////////////
// Carousel
///////////////////////////////////////////////////////////////////////////////
function Carousel(ID, LayerID, MouseTracker, CarouselWidth, ItemWidth, ItemHeight) {
    ///-data-//////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////

    var This = this;

    this._ID = ID;
    this._layerID = LayerID;
    this._interval = '';
    this._items = new Array();
    this._width = CarouselWidth;
    this._itemSize = new Vector2D(ItemWidth, ItemHeight);
    this._itemPosition = new Vector2D((this._width - this._itemSize._x) / 2, 10);
    this._rotateSpeed = 0;
    this._rotateCos = 0;
    this._rotateSin = 0;
    this._mouseTracker = MouseTracker;


    ///-methods-///////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////

    this.AddItem = function(HREF, ImageSRC, url, text) {
        this._items[this._items.length] = new CarouselItem(this, HREF, ImageSRC, url, text);
    };

    this.DrawItems = function() {
        var layer = wGet(this._layerID);
        if (layer) {
            layer.style.width = this._width + 'px';
            layer.style.height = (this._itemPosition._y * 2 + this._itemSize._y) + 'px';

            this.SetRotate((2 * Math.PI) / this._items.length);

            var itemPosition = new Vector2D(0, 1);
            var markup = '';

            for (var count = 0; count < this._items.length; ++count) {
                this._items[count]._element = null;
                this._items[count]._position = itemPosition.Clone();
                markup += this._items[count].GetMarkup();

                this.Rotate(itemPosition);
            }

            markup += '<a href="#" onclick="' + this._ID + '.ClickPrev();" class="prev"></a>';
            markup += '<a href="#" onclick="' + this._ID + '.ClickNext();" class="next"></a>';

            layer.innerHTML = markup;
        }
    };

    this.Animate = function() {
        this.Decelerate();

        for (var count = 0; count < this._items.length; ++count)
            this._items[count].Update();

        if (this._rotateSpeed >= 0 && this._rotateSpeed < 0.1 ||
            this._rotateSpeed < 0 && this._rotateSpeed > -0.1)
            this.Stop();
    };

    this.Start = function() {
        if (this._interval == '')
            this._interval = setInterval(this._ID + '.Animate()', 10);
    };

    this.Stop = function() {
        if (this._interval != '')
            clearInterval(this._interval);

        this._interval = '';
    };

    this.SetRotate = function(Angle) {
        this._rotateCos = Math.cos(Angle);
        this._rotateSin = Math.sin(Angle);
    };

    this.Rotate = function(Vector) {
        var clone = Vector.Clone();
        Vector._x = this._rotateCos * clone._x - this._rotateSin * clone._y;
        Vector._y = this._rotateSin * clone._x + this._rotateCos * clone._y;
    };

    this.Decelerate = function() {
        this._rotateSpeed *= 0.96;
        this.SetRotate((this._rotateSpeed * Math.PI) / 500);
    };

    this.MouseDown = function(Event) {
        if (window.event && !Event)
            Event = window.event;

        if (Event) {
            if (Event.preventDefault)
                Event.preventDefault();
        }

        this._mouseTracker.StopSelect();
        this._rotateSpeed = 0;
    };

    this.Drag = function() {
        if (this._mouseTracker._buttonDown) {
            this._rotateSpeed = -this._mouseTracker._acceleration._x;

            this._mouseTracker.Reset();
            this.Start();
        }
    };

    this.ClickItem = function(ItemID, url) {
        if (this._rotateSpeed == 0 && !this._mouseTracker._buttonDown)
            alert('You clicked item ' + ItemID + ' (' + url + ')');
    };

    this.ClickNext = function() {
      this._rotateSpeed = 10;
      this.Start();
    };

    this.ClickPrev = function() {
      this._rotateSpeed = -10;
      this.Start();
    };
}
