var VDock = new Class({
    Implements: Options,
    
    options: {
        itemSelector: 'li',
        states: {},  
        preloadInterval: 500,
        imageSwapDelay: 0.5,
        defaultTransitionOpts: {'duration': 500},
        preloadCallback: null
    },
    dock: null,
    items: null,
    preloadCount: 0,   
    loaded: 0,
    imageCache: {},

    initialize: function(dock, options) {
        this.setOptions(options);
        this.dock = $(dock);
        this.items = this.dock.getElements(this.options.itemSelector);
        var ims;
        this.items.each(function(el) {
            ims = el.getElements("img");
            ims.each(function(i) {
                i.store('origSrc', i.get('src'));
            });
            el.store('images', ims);
        });
    },
    addStates: function(stateObj) {
        for(id in stateObj) {
            this.options.states[id] = stateObj[id];
            var src; var im; var body = $$('body')[0]; var srcs;

            this.items.retrieve('images').each(function(ims) {
                ims.each(function(im) {          
                    src = im.get('src');
                    if(stateObj[id]['imageReplace']) src = src.replace(
                        stateObj[id]['imageReplace'][0],
                        stateObj[id]['imageReplace'][1]
                    );
                    if(!this.imageCache[id+"__"+src]) {
                        this.preloadCount += 1;
                        img = new Element('img', {'src': src+"?time="+$time()});
                        img.setStyle("display", "none");
                        img.inject(body);
                        img.addEvent("load", function(ev, img, src, id) { 
                            if(Browser.Engine.trident4) {
                                //IE6 Png Fix
                                Browser.fixPNG(img);
                            }
                            this.loaded += 1;
                            this.imageCache[id+"__"+src] = {
                                'image': img,
                                'size': stateObj[id]['imageDimensions'] || 
                                    img.getDimensions( )
                            };
                            img.dispose();
                            img.setStyle("display", "");
                        }.bindWithEvent(this, [img, src, id]));
                    }
                    srcs = im.retrieve('src');
                    if(!srcs) srcs = {};
                    srcs[id] = src;
                    im.store('src', srcs); 
                }.bind(this));
            }.bind(this));
        }
        if(this.preloadTimer) $clear(this.preloadTimer);
        this.preloadTimer = (function ( ) {
            if(this.loaded >= this.preloadCount) {
                $clear(this.preloadTimer);
                this.preloadComplete = true;
                if(this.options.preloadCallback) {
                    this.options.preloadCallback.bind(this)();
                }
            }
        }).periodical(500, this);
    },
    addEventHandler: function(event, handler, items) {
        if(!items) items = this.items;
        items.each(function(i) {
            i.addEvent(event, handler.bindWithEvent(this, [i]));
        });
    },
    morphState: function(state, items) {
        while(!this.preloadComplete) {
            return this.morphState.delay(this.options.preloadInterval, 
                this, [state, items]);
        }

        this.dock.setStyle("overflow", "");

        var aState = this.options.states[state];
        if(!aState) return false;
        if(!items) items = this.items;

        var opts = aState['transitionOptions'] ||
            this.options.defaultTransitionOpts;
        var ims;
        var imc;
        var srcs;
        var count;
        var duration;
        var size;
        var u;
        items.each(function(el) {
            el.getElements("img").each(function(i) {
                srcs = i.retrieve('src');
                if(srcs && srcs[state]) {
                    count = 0;
                    imc = this.imageCache[state+"__"+srcs[state]];
                    duration = i.get('morph').options.duration * 
                        this.options.imageSwapDelay;
                    i.set('morph', opts);
                    i.morph({'width': imc.size.width, 'height': imc.size.height});
                    var u = new URI(i.get('src'));
                    u.set('query', null);
                    if(u.toString() != imc.image.get('src')) {
                        duration = i.get('morph').options.duration * 
                            this.options.imageSwapDelay;
                        (function(i, s) {
                            i.set('src',s); 
                        }).delay(duration, this, [i, imc.image.get('src')]);
                    }
                }
            }.bind(this));
            el.store('morphState', state);
            el.set('morph', opts);
            el.morph('.'+aState['class']);
        }.bind(this));        

        return true;
    }
});

