var Slider = function(container, itemsPerPage, controlsContainer) {
    this.ItemsPerPage = itemsPerPage;
    if(container.nodeName) {
        this.Outer = $(container);
        this.Init();
    } else {
        //Assume it's an ID
        var me = this;
        $(document).ready(function() {
            me.Outer = $('#' + container);
            me.ControlsContainer = $('#' + controlsContainer);
            me.Init();
        });
    }
}
Slider.prototype = {
    CurrPage: null,
    Outer: null,
    Inner: null,
    ControlsContainer: null,
    ItemsPerPage: null,
    ItemWidth:null,
    MaxPageIndex: null,
    PageWidth: null,
    OnAuto: true,
    AutoPlaySpeed: 'slow',
    PlaySpeed: 'medium',
    DelayTime: 5000,
    
    Init: function() {
        //Initialize and get the width of the outer container
        var maxWidth = this.Outer.width();
        this.Outer.css('overflow', 'hidden');
        
        //Initialize the inner container
        this.Inner = this.Outer.find(".sliderInner");
        this.Inner.width(10000);
        //this.Inner.height(this.Outer.height());
        
        //Initialize the items
        var items = this.Inner.find(".item");
        items.css('float', 'left');
        this.ItemWidth = Math.floor(maxWidth / this.ItemsPerPage);
        var realWidth = this.ItemWidth;
        realWidth -= items.css('margin-left').replace('px', '') * 1;
        realWidth -= items.css('margin-right').replace('px', '') * 1;
        items.width(realWidth);
        
        //Initizalize page values
        this.MaxPageIndex = Math.ceil(items.length / this.ItemsPerPage) - 1;
        this.PageWidth = this.ItemWidth * this.ItemsPerPage;
        
        //Set up the controls
        var me = this;
        $('<span class="previous">&lt;</span>').click(function() {
            me.OnAuto = false;
            me.Previous();
        }).appendTo(this.ControlsContainer);
        for(var i = 0; i <= this.MaxPageIndex; i ++) {
            $('<span class="page">' + (i + 1) + '</span>').click(function() {
                me.OnAuto = false;
                me.SwitchTo((this.innerHTML * 1) - 1, true);
            }).appendTo(this.ControlsContainer);
        }
        $('<span class="next">&gt;</span>').click(function() {
            me.OnAuto = false;
            me.Next();
        }).appendTo(this.ControlsContainer);

        this.SwitchTo(0, false);
        
        setTimeout(function() {
            me.Autoplay();
        }, this.DelayTime);

    },
    Autoplay: function() {
        if(this.OnAuto) {
            this.Next();
            var me = this;
            setTimeout(function() {
                me.Autoplay();
            }, this.DelayTime);
        }
    },
    SwitchTo: function(pageIndex, animateChange) {
        this.CurrPage = pageIndex;
        var newPos = pageIndex * this.PageWidth;
        //console.log('%d, %d, %d', pageIndex, this.PageWidth, newPos);
        var speed = (this.OnAuto)?this.AutoPlaySpeed:this.PlaySpeed;
        if(animateChange) {
            this.Outer.animate({
                scrollLeft: newPos
            }, speed);
        } else {
            this.Outer.scrollLeft(newPos);
        }
        this.UpdateControls();
    },
    Previous: function() {
        if(this.CurrPage > 0) this.SwitchTo(this.CurrPage - 1, true);
        else this.JumpToEnd();
    },
    Next: function() {
        if(this.CurrPage < this.MaxPageIndex) this.SwitchTo(this.CurrPage + 1, true);
        else this.JumpToBeginning();
    },
    JumpToBeginning: function() {
        this.JumpTo(0);
    },
    JumpToEnd: function() {
        this.JumpTo(this.MaxPageIndex);
    },
    JumpTo: function(pageIndex) {
        var me = this;
        this.Inner.fadeOut('fast', function() {
            //Hack to get around JQuery's use of display:none for fading out
            me.Inner.css('visibility', 'hidden');
            me.Inner.css('display', 'block');
            me.SwitchTo(pageIndex, false);
            me.Inner.css('display', 'none');
            me.Inner.css('visibility', 'visible');
            me.Inner.fadeIn('fast');
        });
    },
    UpdateControls: function() {
        var me = this;
        this.ControlsContainer.find('span').each(function() {
            if(this.innerHTML == (me.CurrPage + 1) + '') $(this).addClass('active');
            else $(this).removeClass('active');
        });
    }
}
var Popout = function(nodeId, imgSrc, containerId, side, top) {
    this.NodeId = nodeId;
    this.ImgSrc = imgSrc;
    this.ContainerId = containerId;
    this.Side = side;
    this.Top = top;
    this.Bind();
}
Popout.prototype = {
    NodeId: null,
    ImgSrc: null,
    ImgId: null,
    ContainerId: null,
    Side: null,
    Top: null,
    Left: null,
    
    Bind: function() {
        //Horrible cheat 'cause JQuery's event scope blows.  Safe since we don't store node references.
        document.getElementById(this.NodeId)['_Popout'] = this;
        $('#' + this.NodeId).hover(this._NodeIn, this._NodeOut);
        this.ImgId = this.NodeId + '_popout';
        var img = new Image();
        img.id = this.ImgId;
        img.src = this.ImgSrc;
        var me = this;
        img.onload = function() {
            img.style.position = 'absolute';
            img.style.marginTop = me.Top + 'px';
            var container = document.getElementById(me.ContainerId);
            container.appendChild(img);
            me.Left = 0;
            if(me.Side == 'right'){
                me.Left = $(container).width() - $(img).width();
                img.style.marginLeft = me.Left + 'px';
            }
        }
    },
    
    
    _NodeIn: function(e) {
        var p = this._Popout;
        p.lastStart = new Date().getTime();
        var img = $('#' + p.ImgId);
        var target = p.Left;
        if(p.Side == 'left')
            target -= img.width();
        else
            target += img.width();
        img.animate({
            marginLeft: target + 'px'
        }, 'normal');
    },
    _NodeOut: function(e) {
        var p = this._Popout;
        var diff = new Date().getTime() - p.lastStart;
        var delay = 800 - diff;
        if(delay < 0) delay = 1;
        setTimeout(function() {
            var img = $('#' + p.ImgId);
            var target = p.Left;
            img.animate({
                marginLeft: target + 'px'
            }, 'normal');
        }, delay);
    }
}