
Element.implement({
    // Add this onto the Element class for convenience.
    // Means we can just call element.getNumericId();
    getNumericID: function(prefix) {
        if (!prefix)
            prefix = 'item_';
        return this.get('id').replace(prefix, '').toInt();
    },

    // Sets the opacity of any contained select elements
    // Only needed for the IE6 (trident4) browser engine, because it sucks.
    setSelectsOpacity: function(value) {
        if (Browser.Engine.trident4) {
            this.getElements('select').each(function (elem) {
                elem.setStyle('opacity', value);
            });
        }
    }
});

Array.implement({
    // Finds the first element for which test returns true
    find: function(test) {
        for (var i = 0; i < this.length; i++) {
            if (test(this[i])) {
                return this[i];
            }
        }
        return null;
    },

    // Returns an element with a matching ID
    // Assumes an array of hashes
    byID: function(id) {
        return this.find(function(elem) { return elem['id'] == id });
    }
});

var Swish = new Class({

    // Main init, and hooking up of events that makes it all work
    initialize: function() {
        this.isSetup = false;
        var swisher = $('swisher');
        var swishee = $('swishee');

        // I hate IE.
        if (!swisher || !swishee) {
            var _this = this;
            window.addEvent('load', function() {
                _this.setup($('swisher'), $('swishee'));
            });
        } else {
            this.setup(swisher, swishee);
        }
    },

    setup: function(swisher, swishee) {
        this.isSetup = true;
        
        // This is so we can refer to this instance from our closures
        var _this = this;
        
        // Used to determine whether we're in the middle of a transition or not.
        this.inProgress = false;

        // A list of products in JSON format
        this.products = null;

        var fullWidth = $E('#swisher table').getSize().x;
        //var swisher = $('swisher'); - passed in now

//        this.scroller = new Scroller(swisher, {
//            area: 225,
//            velocity: 0.1
//        });
//
//        this.scroller.start();
        
        $$('#swisher a').each(function(link) {
            var item_number = link.getNumericID('thumb_');
            link.addEvent('click', function(event) {
                if (!_this.inProgres) {
                    _this.inProgress = true;
        
                    // If we don't pause the scroller it can interfere with our transition (jerkyness)
//                    _this.scroller.stop();
                    var swishee = $('swishee');
                    var toShow = _this.swish_items[item_number];

		    // This should only be false if you click on the first product thumb before clicking
		    // on any of the others.
		    if (toShow != null) {
			var current = _this.current;
			var gone_id = current.getNumericID();

			toShow.setSelectsOpacity(0);
			current.setSelectsOpacity(0);

			if (toShow != current) {
			    current_fx = current.retrieve('fx');
			    toShow_fx = toShow.retrieve('fx');
			    
			    _this.loadImage(toShow);
			    
			    current_fx.start({ opacity: 0.0 }).chain(function() {
				    _this.swish_items[gone_id] = current.dispose();
				    
				    toShow.inject(swishee, 'top');
				    
				    toShow_fx.start({ opacity: 1.0 }).chain(function() {
//					    _this.scroller.start();
					    _this.inProgress = false;
					    toShow.setSelectsOpacity(1.0);
					});
				});
			    
			    _this.current = toShow;
			}
		    }
                }

                event.stop();
            });
        });

        this.swish_items = $H();

        var first = true;
        // var swishee = $('swishee'); - passed in now
        swishee.getChildren().each(function(child) {
            var id = child.getNumericID();

            child.store('fx',
                        new Fx.Morph(child, {
                            duration: 'short',
                            transition: Fx.Transitions.Sine.easeOut
                        }));

            if (first) {
                first = false;
                _this.current = child;
            } else {
                child.setStyle('opacity', 0);
                _this.swish_items[id] = child.dispose();
            }        
        });

        if (this.shouldLoadProducts) {
            this._loadProductsReal(this.shouldLoadProducts);
        }

        // Check to see if we've gotten a URL from the page because
        // IE runs the domready events in a different order
        var shouldLoadProducts = window.retrieve('shouldLoadProducts');
        if (shouldLoadProducts) {
            this.loadProducts(shouldLoadProducts);
        }
    },

    _loadProductsReal: function(products_url) {
        var _this = this;

        new Request.JSON({
            url: products_url,
            onComplete: function(products) {
                _this.products = products;
                _this.loadImage(_this.current);
            }
        }).get();
    },

    // Request a list of products and their images in JSON format
    loadProducts: function (products_url) {
        if (this.isSetup) {         
            this._loadProductsReal(products_url);
        } else {
            this.shouldLoadProducts = products_url;
        }
    },

    // Loads an image into an element.
    // number is optional, if provided will load a particular image for a product
    loadImage: function (elem, number) {
        if (this.products) {
            var product = this.products.find(function (prod) {
                return prod.id == elem.getNumericID();
            });

            if (product) {
                var image = null;

                if (!number) {
                    image = product.images[0];
                } else {
                    image = product.images.byID(number);
                }
                
                var img = new Asset.image(image.filename);
                
                var shots = elem.getElement('.product_shots');
                shots.empty();
                img.inject(shots);
            }
        }
    },

    loadImageIntoCurrent: function(number) {
        this.loadImage(this.current, number);
    }
});

window.store('swishReady', function() {
    window.addEvent('domready', function() {
        if ($('swisher')) {
            var swish = new Swish();
            window.store('swish', swish);
        } else {
            window.addEvent('load', function() {
                if ($('swisher')) {
                    var swish = new Swish();
                    window.store('swish', swish);
                }
            });
        }
    });
});
