﻿//千一网络 www.cftea.com
//Exhibition v1.0 MIT
//http://www.cftea.com/products/webComponents/Exhibition/
//需要 EZJ v1.0
//ExhibitionScrollStage 需要 ScrollBinder v1.0.1
//ExhibitionFilterStage 需要 Filter 类
//此文件为 UTF-8 格式
//应用示例：
/*
ar data = new ExhibitionData();
data.addItem("1", "<a href='http://www.cftea.com/' target='_blank'><img src='1.png' alt='1' title='' /></a>");
data.addItem("2", "<a href='http://www.cftea.com/' target='_blank'><img src='2.png' alt='2' title='' /></a>");
data.addItem("3", "<a href='http://www.cftea.com/' target='_blank'><img src='3.png' alt='3' title='' /></a>");
data.addItem("4", "<a href='http://www.cftea.com/' target='_blank'><img src='4.png' alt='4' title='' /></a>");
data.addItem("5", "<a href='http://www.cftea.com/' target='_blank'><img src='5.png' alt='5' title='' /></a>");

//var stage = new ExhibitionStage();
var stage = new ExhibitionScrollStage();
//var stage = new ExhibitionFilterStage();
stage.create(data, 325, 200, false);

var controller = new ExhibitionNumberController();
controller.create(data, "mouseover", 3000, 150, 20);

var exhibition = new Exhibition("demo", 2, 1, "solid", "#666666", 325, 200);
exhibition.assemble(stage, 0, 0, controller, 178, 218);
exhibition.initialize();
exhibition.startAutoPlay();
*/


function ExhibitionData()
{
    this.items = new Array();
}


ExhibitionData.prototype.getItemsCount = function ()
{
    return this.items.length;
}


ExhibitionData.prototype.getItemTitle = function (index)
{
    return this.items[index].title;
}


ExhibitionData.prototype.getItemContent = function (index)
{
    return this.items[index].content;
}


ExhibitionData.prototype.addItem = function (title, content)
{
    this.items.push({title:title, content:content});
}


//================================================================================
//================================================================================


function ExhibitionStage()
{
    this.data = null;
    this.width = null;
    this.height = null;
    this.xArrangement = null;
    
    this.currentItemIndex = -1;
    
    
    this.getList = function ()
    {
        return this.container.childNodes[0];
    }
    
    
    this.getItemsCount = function ()
    {
        var list = this.getList();
        if (list.childNodes)
        {
            return list.childNodes.length;
        }
        
        return 0;
    }
    
    
    this.getItem = function (itemIndex)
    {
        return this.getList().childNodes[itemIndex];
    }
    
    
    this.createItems = function ()
    {
        var ul = $C("ul", null, this.container);
        for (var i = 0; i < this.data.getItemsCount(); i++)
        {
            var li = $C("li", null, ul);
            li.innerHTML = data.getItemContent(i);
        }
    }
    
    
    this.setStyle = function ()
    {
        this.container.style.width = parseInt(this.width) + "px";
        this.container.style.height = parseInt(this.height) + "px";
        this.container.style.overflow = "hidden";
        
        var list = this.getList();
        list.style.margin = "0px 0px 0px 0px";
        list.style.padding = "0px 0px 0px 0px";
        if (this.xArrangement)
        {
            list.style.width = parseInt(this.width) * this.getItemsCount() + "px";
        }
        list.style.listStyleType = "none";
        
        for (var i = 0; i < this.getItemsCount(); i++)
        {
            var li = this.getItem(i);
            
             //每个项目和 stage 等大小，同时避免 li 间的缝隙。
            if (this.xArrangement)
            {
                li.style.styleFloat = "left";
                li.style.cssFloat = "left";
                li.style.float = "left";
            }
            li.style.width = parseInt(this.width) + "px";
            li.style.height = parseInt(this.height) + "px";
            li.style.lineHeight = "100%";
            li.style.fontSize = "0px";
        }
    }
}


//装载控制器的容器，调用 create 函数时自动产生。
ExhibitionStage.prototype.container = null;


//创建舞台。
ExhibitionStage.prototype.create = function (data, width, height, xArrangement)
{
    this.data = data;
    this.width = width;
    this.height = height;
    this.xArrangement = xArrangement;
    
    this.container = $C("div");
    this.createItems();
    this.setStyle();
}


//初始化控制器。
ExhibitionStage.prototype.initialize = function ()
{
    this.activateItem(0);
}


//激活项目。
ExhibitionStage.prototype.activateItem = function (itemIndex)
{
    this.currentItemIndex = itemIndex;
    
    if (this.xArrangement)
    {
        this.container.scrollLeft = this.container.clientWidth * this.currentItemIndex;
    }
    else
    {
        this.container.scrollTop = this.container.clientHeight * this.currentItemIndex;
    }
}


//================================================================================
//================================================================================


function ExhibitionScrollStage()
{
    this.parentCreate = this.create; //父类的 create 函数。
    this.scrollBinder = null;
    this.itemsCount = 0; //由于绑定自动滚动可能会增加一些代码，导致 getItemsCount 函数不能用，所以在绑定之前先将其值存储起来。
    
    
    this.create = function (data, width, height, xArrangement)
    {
        this.parentCreate(data, width, height, xArrangement); //调用父类的 create 函数。
        this.itemsCount = this.getItemsCount();
        
        if (xArrangement)
        {
            this.scrollBinder = new ScrollBinder(this.container, "left", 10, 50, 0);
        }
        else
        {
            this.scrollBinder = new ScrollBinder(this.container, "up", 10, 50, 0);
        }
        
        this.scrollBinder.onMoving = function (distance)
        {
            return Math.max(Math.floor(distance / 5), 10);
        }
    }
    
    
    this.activateItem = function (itemIndex)
    {
        var oldItemIndex = this.currentItemIndex;
        var newItemIndex = itemIndex;
        var scrollIndex = itemIndex; //向下、向右滚动时，ScrollBinder 的屏索引是最下、最右为零。
        this.currentItemIndex = itemIndex;
        
        //这里是用来设置滚动是否需要掉转方向的。
        //这样就不会滚向旁边一屏时都去转一圈，而是掉转方向直接到达。
        if (oldItemIndex >= 0 && newItemIndex > oldItemIndex)
        {
            if ((newItemIndex - oldItemIndex) > (this.itemsCount / 2))
            {
                this.scrollBinder.direction = (this.xArrangement) ? "right" : "down";
                scrollIndex = this.itemsCount - 1 - scrollIndex;
            }
            else
            {
                this.scrollBinder.direction = (this.xArrangement) ? "left" : "up";
            }
        }
        else if (oldItemIndex >= 0 && oldItemIndex > newItemIndex)
        {
            if ((oldItemIndex - newItemIndex) > (this.itemsCount / 2))
            {
                this.scrollBinder.direction = (this.xArrangement) ? "left" : "up";
            }
            else
            {
                this.scrollBinder.direction = (this.xArrangement) ? "right" : "down";
                scrollIndex = this.itemsCount - 1 - scrollIndex;
            }
        }
        
        //滚动到指定屏。
        this.scrollBinder.start("screen", scrollIndex, true, true);
    }
}


//继承
ExhibitionScrollStage.prototype = new ExhibitionStage();
ExhibitionScrollStage.prototype.constructor = ExhibitionScrollStage;


//================================================================================
//================================================================================


function ExhibitionFilterStage()
{
    this.filter = new Filter();
    this.filter.SetAsGradientWipe("1", "0.5", "0", "forward");
    
    
    this.activateItem = function (itemIndex)
    {
        if (this.currentItemIndex >= 0)
        {
            try
            {
                this.container.style.filter = this.filter.filterStr;
                this.container.filters.item(this.filter.filterName).apply();
                this.container.style.visibility = "hidden";
                this.container.filters.item(this.filter.filterName).play();
            }
            catch (ex)
            {
                this.container.style.visibility = "hidden";
            }
        }
        
        this.currentItemIndex = itemIndex;
        
        if (this.xArrangement)
        {
            this.container.scrollLeft = this.container.clientWidth * this.currentItemIndex;
        }
        else
        {
            this.container.scrollTop = this.container.clientHeight * this.currentItemIndex;
        }
        
        this.container.style.visibility = "visible";
    }
}


//继承
ExhibitionFilterStage.prototype = new ExhibitionStage();
ExhibitionFilterStage.prototype.constructor = ExhibitionFilterStage;


//================================================================================
//================================================================================


function ExhibitionController()
{
    this.data = null;
    this.eventName = null;
    this.delay = null;
    this.width = null;
    this.height = null;
    
    this.currentItemIndex = -1;
    this.autoPlay = false;
    this.timer = null;
    
    
    this.getList = function ()
    {
        return this.container.childNodes[0];
    }
    
    
    this.getItemsCount = function ()
    {
        var list = this.getList();
        if (list.childNodes)
        {
            return list.childNodes.length;
        }
        
        return 0;
    }
    
    
    this.getItem = function (itemIndex)
    {
        return this.getList().childNodes[itemIndex];
    }
    
    
    this.createItems = function ()
    {
        var list = $C("ul", null, this.container);
        for (var i = 0; i < this.data.getItemsCount(); i++)
        {
            var li = $C("li", null, list);
            this.bindButtonEvent(i);
            li.innerHTML = this.data.getItemTitle(i);
        }
    }
    
    
    this.bindButtonEvent = function (itemIndex)
    {
        var li = this.getItem(itemIndex);
        var me = this;
        var n = itemIndex;
        if (window.attachEvent)
        {
            li.attachEvent("on" + this.eventName, function () { me.handleButtonEvent(true, n); });
            li.attachEvent("onmouseout", function () { me.handleButtonEvent(false, n); });
        }
        else
        {
            li.addEventListener(this.eventName, function () { me.handleButtonEvent(true, n); }, false);
            li.addEventListener("mouseout", function () { me.handleButtonEvent(false, n); }, false);
        }
    }
    
    
    this.handleButtonEvent = function (access, itemIndex)
    {
        if (access)
        {
            //进入按钮
            clearInterval(this.timer);
            this.timer = null;
            this.activateItem(itemIndex);
        }
        else if (this.autoPlay && (this.timer == null))
        {
            //离开按钮，并且需要自动播放，并且目前没有自动播放
            this.startAutoPlay(false);
        }
    }
    
    
    this.setNormalButtonStyle = function (itemIndex)
    {
    }
    
    
    this.setActiveButtonStyle = function (itemIndex)
    {
    }
    
    
    this.setStyle = function ()
    {
        this.container.style.width = parseInt(this.width) + "px";
        this.container.style.height = parseInt(this.height) + "px";
        this.container.style.overflow = "hidden";
        
        var list = this.getList();
        list.style.margin = "0px 0px 0px 0px";
        list.style.padding = "0px 0px 0px 0px";
        list.style.listStyleType = "none";
        
        for (var i = 0; i < this.getItemsCount(); i++)
        {
            this.setNormalButtonStyle(i);
        }
    }
    
    
    this.activateItem = function (itemIndex)
    {
        this.setNormalButtonStyle(this.currentItemIndex);
        
        if (itemIndex < 0 || itemIndex >= this.getList().childNodes.length)
        {
            itemIndex = 0;
        }
        this.currentItemIndex = itemIndex;
        
        this.setActiveButtonStyle(this.currentItemIndex);
        
        if (typeof(this.onItemActivated) == "function")
        {
            this.onItemActivated(this.currentItemIndex);
        }
    }
}


//装载控制器的容器，调用 create 函数时自动产生。
ExhibitionController.prototype.container = null;


//事件。
//当某个项目被激活时触发。
//传入两个参数：itemIndex，表示哪个项目被激活了。
ExhibitionController.prototype.onItemActivated = null;


//创建控制器。
ExhibitionController.prototype.create = function (data, eventName, delay, width, height)
{
    this.data = data;
    this.eventName = eventName;
    this.delay = delay;
    this.width = width;
    this.height = height;
    
    this.container = $C("div");
    this.createItems();
    this.setStyle();
}


//初始化控制器。
ExhibitionController.prototype.initialize = function ()
{
    this.activateItem(0);
}


//设置是否自动播放。
//参数 immediatelyNext，布尔。是否立即进入下一个项目。
ExhibitionController.prototype.startAutoPlay = function (immediatelyNext)
{
    this.autoPlay = true;
    
    if (immediatelyNext)
    {
        this.activateItem(this.currentItemIndex + 1);
    }
    
    var me = this;
    this.timer = setInterval(function () { me.activateItem(me.currentItemIndex + 1); }, this.delay);
}


//================================================================================
//================================================================================


function ExhibitionNumberController()
{
    this.setNormalButtonStyle = function (itemIndex)
    {
        if (itemIndex >= 0 && itemIndex < this.container.childNodes[0].childNodes.length)
        {
            var li = this.getItem(itemIndex);
            li.style.marginLeft = (itemIndex >= 1) ? "3px" : "0px";
            li.style.padding = "3px 5px 3px 5px";
            li.style.border = "1px solid #FF0000";
            li.style.styleFloat = "left"; //IE、Opera 支持
            li.style.cssFloat = "left"; //Firefox、Chrome、Opera、Safari 支持
            li.style.float = "left"; //Chrome、Safari 支持
            li.style.lineHeight = "100%";
            li.style.overflow = "hidden";
            li.style.color = "#FFFFFF";
            li.style.backgroundColor = "#000000";
            li.style.fontSize = "12px";
            li.style.fontWeight = "normal";
            li.style.textAlign = "center";
            li.style.cursor = "pointer";
        }
    }
    
    
    this.setActiveButtonStyle = function (itemIndex)
    {
        if (itemIndex >= 0 && itemIndex < this.container.childNodes[0].childNodes.length)
        {
            var li = this.getItem(itemIndex);
            li.style.marginLeft = (itemIndex >= 1) ? "3px" : "0px";
            li.style.padding = "3px 5px 3px 5px";
            li.style.border = "1px solid #FF0000";
            li.style.styleFloat = "left"; //IE、Opera 支持
            li.style.cssFloat = "left"; //Firefox、Chrome、Opera、Safari 支持
            li.style.float = "left"; //Chrome、Safari 支持
            li.style.lineHeight = "100%";
            li.style.overflow = "hidden";
            li.style.color = "#FFFFFF";
            li.style.backgroundColor = "#CC0000";
            li.style.fontSize = "12px";
            li.style.fontWeight = "bold";
            li.style.textAlign = "center";
            li.style.cursor = "pointer";
        }
    }
}


//继承
ExhibitionNumberController.prototype = new ExhibitionController();
ExhibitionNumberController.prototype.constructor = ExhibitionNumberController;


//================================================================================
//================================================================================


function Exhibition(target, padding, borderWidth, borderStyle, borderColor, width, height)
{
    this.target = $(target);
    this.container = $C("div");
    this.containerAsst = $C("div", null, this.container); //为了兼容各浏览器而设置的边框及 padding 辅助层
    this.containerAsst2 = $C("div", null, this.containerAsst); //为了设置 width、height 而设置的辅助层
    
    this.stage = null;
    this.controller = null;
    
    var me = this;
    
    function setStyle(padding, borderWidth, borderStyle, borderColor, width, height)
    {
        me.containerAsst.style.padding = parseInt(padding) + "px";
        me.containerAsst.style.borderWidth = parseInt(borderWidth) + "px";
        me.containerAsst.style.borderStyle = borderStyle;
        me.containerAsst.style.borderColor = borderColor;
        
        me.container.style.width = (parseInt(width) + parseInt(borderWidth) * 2 + parseInt(padding) * 2) + "px";
        me.container.style.height = (parseInt(height) + parseInt(borderWidth) * 2 + parseInt(padding) * 2) + "px";
        
        me.containerAsst2.style.position = "relative";
        me.containerAsst2.style.width = parseInt(width) + "px";
        me.containerAsst2.style.height = parseInt(height) + "px";
        me.containerAsst2.style.overflow = "hidden";
    }
    setStyle(padding, borderWidth, borderStyle, borderColor, width, height)
}


Exhibition.prototype.assemble = function (stage, stageTop, stageLeft, controller, controllerTop, controllerLeft)
{
    this.stage = stage;
    $C(this.stage.container, null, this.containerAsst2);
    this.stage.container.style.position = "absolute";
    this.stage.container.style.top = parseInt(stageTop) + "px";
    this.stage.container.style.left = parseInt(stageLeft) + "px";
    
    this.controller = controller;
    $C(this.controller.container, null, this.containerAsst2);
    this.controller.container.style.position = "absolute";
    this.controller.container.style.top = parseInt(controllerTop) + "px";
    this.controller.container.style.left = parseInt(controllerLeft) + "px";
    
    //绑定事件
    //controller 控制 stage
    var me = this;
    var itemActivatedHandler = function (itemIndex)
    {
        me.stage.activateItem(itemIndex);
    }
    if (typeof(this.controller.onItemActivated) == "function")
    {
        //已经绑定有事件处理程序，追加。
        var existsItemActivatedHandler = this.controller.onItemActivated;
        this.controller.onItemActivated = function (itemIndex)
        {
            existsItemActivatedHandler(itemIndex);
            itemActivatedHandler(itemIndex);
        }
    }
    else
    {
        this.controller.onItemActivated = itemActivatedHandler;
    }
    
    //装到 target
    $C(this.container, null, this.target);
}


//初始化，即激活第一个项目。
Exhibition.prototype.initialize = function ()
{
    this.stage.initialize();
    this.controller.initialize();
}


//设置自动播放，即启动项目自动变换。
Exhibition.prototype.startAutoPlay = function ()
{
    this.controller.startAutoPlay(false);
}