// class:           ImageScrOOler
// version:         1.62
// dependencies:    mootools 1.2.x
// tested on:       FireFox 3, IE7, Safari 4 (beta), Opera 9.60
// last updated:    10/09/2009 15:57:01
// url:             http://fragged.org/
// author:          dimitar chrostoff <christoff@gmail.com>
// authorised use:  modify and use as you deem fit. any link back appreciated :)

var ImageScrOOler = new Class({
    Implements: [Options, Events],
    moveDirection: "right",
    moveOffset: 0,
    options: {
        // set defaults here
        targetElement: $empty,  // you NEED the target element to be an object
        imagePath: "",          // prefix images with this
        imageSpacing: 10,       // margin between scrolling images
        imageOpacity: .8,
            // this can open a url or call
        moveDelay: 16,          // animation delay between frames, in ms
        moveSteps: 1,           // move by number of pixels
        imageHeight: 70,        // default image height
        showProgress: true,     // show a 'status' like layer
        defaultMessage: 'Click on the images below',
        showMessage: ' Show me items from ',
        imageClass: 'cur',      // css class to apply to each image, for example, with cursor: pointer
        EOL: 0,              // delay after eaching END-OF-LINE in ms
        carousel: true         // if true, it just recycles images and no EOL is reached, works left to right.
    },
    initialize: function(data, options) {
        // data needs to be an array of JSON like this:
        // var data = [
        //    {image: 'Blowfish.gif', url: '/Blowfish', title: 'Blowfish'},
        //    {image: 'Bronx.gif', url: '/Bronx', title: 'Bronx'} ...
        // ];

        this.setOptions(options);
		this.originalSize = undefined;
        if ($type(this.options.targetElement) != "element")
            return false;

        if(!data.length)
            return false;

        this.data = data;
        this.options.targetElement.empty();

        // setup our elements
        if (this.options.showProgress) // progress / mouseover status element, style #moostats via css
            this.stats = new Element("span", {id: 'moostats', html: "Initialising..."}).inject(this.options.targetElement);

        // containing titles layer
        this.container = new Element("div", {
            styles: {
                overflow: "hidden",
                height: this.options.imageHeight,
                visibility: "hidden",
                width: this.options.targetElement.getSize().x,
                float: "left"
            }
        }).inject(this.options.targetElement);

        this.subcontainer = new Element("div", {
            styles: {
                overflow: "hidden",
                height: this.options.imageHeight,
                visibility: "hidden",
                width: this.options.targetElement.getSize().x,
                "white-space": "nowrap"
            }
        }).inject(this.container);

        // load images and start moving.
        this.loadAssets();

        // prepare containers and make visible
        this.container.setStyles({
            visibility: "visible",
            opacity: 0.1
        }).fade(0,1);

        this.subcontainer.addEvents({
            mouseleave: function() {
                this.move();
            }.bind(this),
            mouseenter: function() {
                this.stop();
            }.bind(this)
        }).setStyle("visibility", "visible");

        if (this.options.showProgress)
            this.stats.set("html", this.options.defaultMessage);
        // get going!
        this.stop(); // clear up reload issues
        this.subcontainer.scrollTo(0,0);
        this.move();
    },
    loadAssets: function() {
        // injects images into our containers.
        var _this = this; // can't bind this for the images onload so save a ref.

        this.subcontainer.empty();
        // loop array
		this.count = 0;
		this.theLink = new Array();
        this.data.each(function(el, i) {
			_this.theLink[_this.count] = new Asset.hlink(el.onclicking);
			_this.theLink[_this.count].inject(_this.subcontainer);
			new Asset.image(_this.options.imagePath + el.image, {
                title: el.title,
				//onclick: el.onclicking,
                "class": "mOOimage",
                onload: function() {
                    if (i < _this.data.length)
                        this.setStyle("margin-right", _this.options.imageSpacing);

                    // add css settings to images here or change / force height.
                    this.set({
                        styles: {
                            height: _this.options.imageHeight
                        },
                        opacity: _this.options.imageOpacity
                    }).addClass(_this.options.imageClass);

                    _this.addImageEvents(this);
                }
            }).inject(_this.theLink[_this.count]);
			_this.count++;

            if (_this.options.showProgress) {
                // output how many loaded
                if (i < _this.data.length)
                    _this.stats.set("html", i + ' loaded...');
            }
        }); // each

        this.subcontainer.scrollTo(0,0);
    },
    addImageEvents: function(img) {
        return img.set({
            events: {
                mouseenter: function() {
                    if (this.options.showProgress && img.get("title") != null)
                        this.stats.set("html", " <span style='color:#666'>" + img.get("title") + "</span>");
                    img.set("opacity", 1);
                }.bind(this),
                mouseleave: function() {
                    if (this.options.showProgress)
                        this.stats.set("html", this.options.defaultMessage);
                    img.set("opacity", this.options.imageOpacity);
                }.bind(this)
            }
        });
    },
    getSize: function() {
        // based on mootools 1.11 getSize, gets the subcontainer size and scroll data
        this.subSize = {
            'scroll': {'x': this.subcontainer.scrollLeft, 'y': this.subcontainer.scrollTop},
            'size': {'x': this.subcontainer.offsetWidth, 'y': this.subcontainer.offsetHeight},
            'scrollSize': {'x': this.subcontainer.scrollWidth, 'y': this.subcontainer.scrollHeight}
        };
    },
    frame: function() {
		if(this.originalSize == undefined){
			this.originalSize = getSize();
		}
        // move one frame in whatever direction and handle stop/turn around.
        if (this.moveDirection == "right") {
            this.getSize();
            this.subcontainer.scrollTo(this.subSize.scroll.x+this.options.moveSteps, 0); // number of pixels

            // carousel -- works left to right only.
            if (this.options.carousel) {
                var first = this.subcontainer.getElements("img.mOOimage")[0];
				var first2 = this.subcontainer.getElements("a.moomoo")[0];

                if (first2) {
                    var firstWidth = first.getStyle("width").toInt() + this.options.imageSpacing;
                    if (this.subSize.scroll.x >= firstWidth + this.moveOffset) {
                        this.moveOffset += firstWidth;
						first2clone = first2.clone();
						first2clone.inject(this.subcontainer);
                        this.addImageEvents(first2clone.getElements("img.mOOimage")[0]); //.inject(first2clone); // moves to end.
                        first2.removeClass("moomoo");
						first.removeClass("mOOimage");
						//first2.dispose();
                    }

                }
                return false;
            }

            this.getSize();
            if (this.subSize.size.x + this.subSize.scroll.x >= this.subSize.scrollSize.x && this.subSize.scroll.x > 0) {
                // reached end of data to right, go left
                this.stop();
                this.fireEvent("complete", this.moveDirection);
                this.moveDirection = "left";

                (function() {
                    this.move();
                }).delay(this.options.EOL, this); // pause at end of line to allow seeing last item
            }


        }
        else {
            this.getSize();
            this.subcontainer.scrollTo(this.subSize.scroll.x-this.options.moveSteps, 0); // move nn pixels

            this.getSize();
            if (this.subSize.scroll.x <= 0) {
                // reached left end of data to left, turn around...
                this.stop();
                this.fireEvent("complete", this.moveDirection);
                this.moveDirection = "right";

                (function() {
                    this.move();
                }).delay(this.options.EOL, this); // pause at end of line to allow seeing last item
            };
        }
    },
    move: function() {
        // drives moving
        this.stop();
        this.moveTimer = (function() {
            this.frame();
        }).periodical(this.options.moveDelay, this);
    },
    stop: function() {
        // stop moving.
        $clear(this.moveTimer);
    },
    turn: function() {
        // swap direction
        this.moveDirection = (this.moveDirection == "right") ? "left" : "right";
        this.subcontainer.getElements("a").filter(function(el) {
            return !el.hasClass("moomoo"); // remove ghost images
        }).dispose();
    }
}); // end ImageScrOOler class

