﻿
/*  Class:           ddImagePreloader
    Description:    Preloades a set (array) of images firing events when complete or 
                    error.  It shows progress via either basic text display or through
                    the dwProgressBar class.
    Requirements:   requires the dwProgressBar.js file even if "basic text display" is used.
                    If the dwProgressBar is used, then the dwProgressBar.css (and its images)
                    can be included for styling.                    
                    
*/
var ddImagePreloader = new Class({

    //implements
    Implements: [Options, Events],

    //options
    options: {
        images: new Array(),    //Array of string (image src)
        useProgressBar: false,
        onStart: $empty,
        onComplete: $empty,
        onError: $empty
    },

    elements: null,
    errorMsg: null,
    progressMsg: null,

    //initialization
    initialize: function(options) {
        //set options
        this.setOptions(options);
        this.elements = null;
        this.errorMsg = null;
        this.progressMsg = "initialize";
    },

    load: function() {
        this.progressMsg = "load";

        //setup start event
        this.fireEvent("start", this);

        if (this.options.images.length == 0) {
            this.errorMsg = "No images to load";
            this.fireEvent("error", this);
        } else {
            this.elements = new Asset.images(this.options.images, {
                onProgress: this._onProgress.bind(this),
                onComplete: this._onComplete.bind(this)
            });
        }
    },

    _onProgress: function(counter, index) {
        this.progressMsg = "counter = " + counter + " and index = " + index;
    },

    _onComplete: function() {
        this.progressMsg = "COMPLETE total = " + this.elements.length;

        //fire onComplete
        this.fireEvent("complete", this);
    }
});





/*  Class:          ddImage
    Description     Expanded Image info including src, alt, and title properties as well as onMouseOver, onMouseOut and onClick events.    
*/
var ddImage = new Class({

    //implements
    Implements: [Options],

    //options
    options: {
        src: '',
        alt: '',
        title: '',
        onMouseover: $empty,
        onMouseout: $empty,
        onClick: $empty
    },

    initialize: function(options) {
        //set options
        this.setOptions(options);
    },

    UpdateImageElement: function(img) {
        img.set("src",this.options.src);
        img.set("alt",this.options.alt);
        img.set("title",this.options.title);
        img.removeEvents();
        img.addEvents({ mouseenter: this.options.onMouseover.bind(this),
                mouseleave: this.options.onMouseout.bind(this),
                click: this.options.onClick.bind(this)
            });
    }, 
    
    CreateImageElement: function(id) {    
        var ret = new Element("img", {
            src: this.options.src,
            alt: this.options.alt,
            title: this.options.title,
            id: id,
            events: { mouseover: this.options.onMouseover.bind(this),
                mouseout: this.options.onMouseout.bind(this),
                click: this.options.onClick.bind(this)
            }
        });
        return ret;
    }
});

/*  Class:          ddGridShowElement 
    Description:    Represents a single section including initial image, 
                    set of thumbs to cover initial image, and final image 
                    that is revealed as thumbs are closed
*/

var ddGridShowElement = new Class({

    //implements
    Implements: [Options, Events],

    //options
    options: {
        title: null,   //String describing section
        titleImg: null,     //ddImage for the title
        initialImg: null,  //ddImage
        finalImg: null, //ddImage
        thumbs: new Array(),    //Array of ddImage
        onStart: $empty,
        onComplete: $empty
    },

    //initialization
    initialize: function(options) {
        //set options
        this.setOptions(options);
    },

    imageSourceList: function() {
        var ret = new Array();
        if ($defined(this.options.initialImg)) { ret.push(this.options.initialImg.options.src); }
        if ($defined(this.options.finalImg)) { ret.push(this.options.finalImg.options.src); }
        this.options.thumbs.each(function(thumb) {
            ret.push(thumb.options.src);
        });
        return ret;
    },

    run: function(target) {
        target = $(target);
        if ($defined(target)) {
            var img = this.options.initialImg.CreateImageElement("test");
            target.appendChild(img);
        }
    }
});

/* Class:           aaGridShow
    Description:    An animated control that displays a set of "sections"
                    each starts with a single image that is then covered
                    by a set of thumbs (grid).  These thumbs are then removed
                    to reveal the next image in the section.  This process
                    repeats with the last section revealing the first.
*/
var ddGridShow = new Class({
    //implements
    Implements: [Options, Events],

    //options
    options: {
        idContainer: 'ddGrid',
        idImageArea: 'ddImageArea',
        idTitleArea: 'ddTitleArea',

        cssMainImage: 'dd-main-image',
        cssGridWrapper: 'dd-grid-wrapper',
        cssClearImage: 'dd-clear-image',
        clearImageSrc: 'images/clear.gif',
        cssLoadingImage: 'dd-loading-image',
        loadingImageSrc: 'images/loading-white-bg.gif',
        delayInitial: 2000,
        delayGridShow: 300,
        delayGridHide: 100,
        delayGridWait: 3000,
        delayFinal: 1000,
        onStart: $empty,
        onReady: $empty
    },

    container: null,
    imageArea: null,
    titleArea: null,
    sections: new Array(),   //array of ddGridShowElement
    mainImage: null,
    gridWrapper: null,
    gridElementArray: new Array(),
    clearImg: null,
    loadingImg: null,
    titleImg: null,
    interval: null,
    currentSectionIndex: null,
    currentGridIndex: null,
    action: null,

    //initialization
    initialize: function(options) {
        //set options
        this.setOptions(options);
        this.container = $(this.options.idContainer);
        if ($defined(this.container)) {
            this.createElements();
        }
    },

    createElements: function() {
        //create the areas
        this.imageArea = new Element("div", { id: this.options.idImageArea });
        this.titleArea = new Element("div", { id: this.options.idTitleArea });
        this.container.adopt(this.imageArea, this.titleArea);

        //create the elements for the image area (main image, grid wrapper, and clear image        
        this.mainImage = new Element("img", { "class": this.options.cssMainImage });
        this.gridWrapper = new Element("div", { "class": this.options.cssGridWrapper });
        this.clearImg = new Element("img", { "class": this.options.cssClearImage,
            src: this.options.clearImageSrc
        });
        this.loadingImg = new Element("img", { "class": this.options.cssLoadingImage,
            src: this.options.loadingImageSrc, styles: { display: "none" }
        });

        this.imageArea.adopt(this.mainImage, this.gridWrapper, this.clearImg, this.loadingImg);

        //create the image for the title
        this.titleImg = new Element("img", { "opacity": 1 });
        this.titleArea.adopt(this.titleImg);

    },


    //title is a string while titleImg is path to image)
    //initialImg is a string (path to initial image)
    //thumbs is array of string (paths to each grid image in order)
    AddSection: function(title, url, titleImg, initialImg, thumbs) {
        var titleImage = new ddImage({ src: titleImg, alt: title, title: title,
            onClick: function() { location.href = url; }
        });
        var sectionImage = new ddImage({ src: initialImg, alt: title, title: title });
        var ddThumbs = new Array();
        thumbs.each(function(path) {
            ddThumbs.push(new ddImage({ src: path, alt: title + ddThumbs.length }));
        }, this);

        this.sections.push(new ddGridShowElement({ title: title,
            titleImg: titleImage,
            initialImg: sectionImage,
            thumbs: ddThumbs
        }));

    },
    Run: function() {
        //reset
        if (this.interval) { clearInterval(this.interval); }
        this.currentGridIndex = 0;

        //preloader
        this.loadingImg.setStyle('display', '');

        var images = new Array();
        this.sections.each(function(section) {
            section.imageSourceList().each(function(src) {
                images.push(src);
            });
        });

        var loader = new ddImagePreloader({ images: images,
            onError: this._onError.bind(this),
            onComplete: this._onComplete.bind(this)
        });

        loader.load();
    },

    _onError: function(arg) {
        alert("Error Loading Images!/n" + arg.errorMsg);
    },

    _onComplete: function(arg) {
        //update each of the finalImg
        for (var i = 0, len = this.sections.length; i < len; i++) {
            var iPrevious = i - 1;
            if (i == 0) { iPrevious = len - 1; }
            this.sections[iPrevious].options.finalImg = this.sections[i].options.initialImg;
        }

        //get started
        this.loadingImg.setStyle('display', 'none');
        this.currentGridIndex = 0;
        this.currentSectionIndex = 0;
        this._loadNextSection();
    },

    _loadNextSection: function() {
        if (this.interval) { clearInterval(this.interval); }
        var section = this.sections[this.currentSectionIndex];
        if ($defined(this.container)) {
            var index = 0;

            //load title image and intialImage
            if (!$defined(this.titleImg.get("src")) || this.titleImg.get("src").length == 0) {
                section.options.titleImg.UpdateImageElement(this.titleImg);
            }
            section.options.initialImg.UpdateImageElement(this.mainImage);

            section.options.thumbs.each(function(thumb) {
                if (index < this.gridElementArray.length) {
                    thumb.UpdateImageElement(this.gridElementArray[index]);
                } else {
                    var img = thumb.CreateImageElement(null);
                    img.setStyle('opacity', 0);
                    this.gridWrapper.appendChild(img);
                    this.gridElementArray.push(img);
                }
                index += 1;
            }, this);

            this.currentGridIndex = 0;
            this.action = 1;
            this.interval = setInterval(this._iterate.bind(this), this.options.delayInitial);
        }
    },
    _showTitle: function() {
        this.sections[this.currentSectionIndex].options.titleImg.UpdateImageElement(this.titleImg);
        this.titleImg.fade(1);
    },

    _iterate: function() {
        if (this.interval) { clearInterval(this.interval); }
        if (this.action == 0) {     //switch
            this.currentGridIndex = this.gridElementArray.length - 1;
            this.action = -1;
            this.sections[this.currentSectionIndex].options.finalImg.UpdateImageElement(this.mainImage);
            this.interval = setInterval(this._iterate.bind(this), this.options.delayGridHide);
        } else if (this.action == 1) {     //show grid
            if (this.currentGridIndex < this.gridElementArray.length) {
                this.gridElementArray[this.currentGridIndex].fade(1);
                this.currentGridIndex++;
            }

            if (this.currentGridIndex < this.gridElementArray.length) {
                this.interval = setInterval(this._iterate.bind(this), this.options.delayGridShow);
            } else {
                this.action = 0;
                this.interval = setInterval(this._iterate.bind(this), this.options.delayGridWait);
            }

        } else {                    //hide grid
            if (this.currentGridIndex >= 0) {
                this.gridElementArray[this.currentGridIndex].fade(0);
                this.currentGridIndex--;
            }

            if (this.currentGridIndex >= 0) {
                this.interval = setInterval(this._iterate.bind(this), this.options.delayGridHide);
            } else {
                this.currentSectionIndex++;
                if (this.currentSectionIndex >= this.sections.length) { this.currentSectionIndex = 0; }

                //title
                var titleFx = new Fx.Tween(this.titleImg, { onComplete: this._showTitle.bind(this) });
                titleFx.start('opacity', 0);

                //next section
                this.interval = setInterval(this._loadNextSection.bind(this), this.options.delayFinal);
            }

        }
    }
});