Album = {

    init: function(elementId, albumDir) {
        var app = new Album.App(albumDir);
        var client = new Echo.FreeClient(app, document.getElementById(elementId));
        client.init();
   }
};

Album.App = Core.extend(Echo.Application, {

    _albumSelect: null,
    _captionLabel: null,
    _previousButton: null,
    _nextButton: null,
    _pictureContainer: null,
    _albumsDirectory: null,
    _pictures: null,
    _pictureIndex: null,
    _pictureSelect: null,
    
    $construct: function(albumsDirectory) {
        this._albumsDirectory = albumsDirectory;

        Echo.Application.call(this);
        this.rootComponent.add(new Echo.ContentPane({
            children: [
                new Echo.SplitPane({
                    orientation: Echo.SplitPane.ORIENTATION_VERTICAL_TOP_BOTTOM,
                    separatorPosition: 30,
                    children: [
                        new Echo.Row({
                            alignment: "center",
                            cellSpacing: 60,
                            children: [
                                new Echo.Row({
                                    cellSpacing: 8,
                                    children: [
                                        new Echo.Label({
                                            text: "Album:"
                                        }),
                                        this._albumSelect = new Echo.SelectField({
                                            events: {
                                                action: Core.method(this, this._processSelectAlbum)
                                            }
                                        })
                                    ]
                                }),
                                new Echo.Row({
                                    cellSpacing: 8,
                                    children: [
                                        this._previousButton = new Echo.Button({
                                            text: "Previous",
                                            icon: "image/Icon24ArrowGreenLeft.gif",
                                            lineWrap: false,
                                            height: 24,
                                            insets: "3px 15px",
                                            rolloverEnabled: "true",
                                            rolloverBackground: "#00007f",
                                            rolloverBackgroundImage: {
                                                url: "image/RolloverBackground.png",
                                                y: "50%"
                                            },
                                            rolloverForeground: "#ffffff",
                                            rolloverIcon: "image/Icon24ArrowLightGreenLeft.gif",
                                            disabledIcon: "image/Icon24ArrowGrayLeft.gif",
                                            disabledForeground: "#7f7f7f",
                                            events: {
                                                action: Core.method(this, this._processPrevious)
                                            }
                                        }),
                                        this._pictureSelect = new Echo.SelectField({
                                            events: {
                                                action: Core.method(this, this._processIndexSelect)
                                            }
                                        }),
                                        this._nextButton = new Echo.Button({
                                            text: "Next",
                                            textPosition: "left",
                                            icon: "image/Icon24ArrowGreenRight.gif",
                                            lineWrap: false,
                                            height: 24,
                                            insets: "3px 15px",
                                            rolloverEnabled: "true",
                                            rolloverBackground: "#00007f",
                                            rolloverBackgroundImage: {
                                                url: "image/RolloverBackground.png",
                                                y: "50%"
                                            },
                                            rolloverForeground: "#ffffff",
                                            rolloverIcon: "image/Icon24ArrowLightGreenRight.gif",
                                            disabledIcon: "image/Icon24ArrowGrayRight.gif",
                                            disabledForeground: "#7f7f7f",
                                            events: {
                                                action: Core.method(this, this._processNext)
                                            }
                                        })
                                    ]
                                })
                            ]
                        }),
                        new Echo.SplitPane({
                            orientation: Echo.SplitPane.ORIENTATION_VERTICAL_BOTTOM_TOP,
                            separatorPosition: 60,
                            children: [
                                new Echo.Row({
                                    layoutData: {
                                        insets: 10,
                                        overflow: Echo.SplitPane.OVERFLOW_HIDDEN
                                    },
                                    alignment: "center",
                                    children: [
                                        this._prefetch = new Album.Prefetch(),
                                        this._captionLabel = new Echo.Label()
                                    ]
                                }),
                                this._pictureContainer = new Extras.TransitionPane()
                            ]
                        })
                    ]
                })
            ]
        }));

        // Retrieve List of Albums
        var conn = new Core.Web.HttpConnection(this._albumsDirectory + "/albums.xml", "GET");
        conn.addResponseListener(Core.method(this, function(e) {
            var albumsDom = e.source.getResponseXml();
            var element = albumsDom.documentElement.firstChild;
            var albums = [];
            while (element) {
                if (element.nodeName == "album") {
                    albums.push({id: element.getAttribute("dir"), text: element.firstChild.nodeValue});
                }
                element = element.nextSibling;
            }
            this._albumSelect.set("items", albums);
            if (albums.length > 0) {
                this._loadAlbum(albums[0].id);
            }
        }));
        conn.connect();
    },
    
    _getPictureUrl: function(index) {
        return this._albumsDirectory + this._currentAlbumDirectory + this._pictures[index].file;
    },
    
    _loadAlbum: function(directory) {
        // Retrieve Album Slide List
        var conn = new Core.Web.HttpConnection(this._albumsDirectory + directory + "/album.xml", "GET");
        this._currentAlbumDirectory = directory;
        conn.addResponseListener(Core.method(this, function(e) {
            var albumDom = e.source.getResponseXml();
            var element = albumDom.documentElement.firstChild;
            var pictures = [];
            while (element) {
                if (element.nodeName == "picture") {
                    var picture = { file: element.getAttribute("file") };
                    if (element.firstChild && element.firstChild.nodeType == 3) {
                        picture.caption = element.firstChild.nodeValue;
                    }
                    pictures.push(picture);
                }
                element = element.nextSibling;
            }
            this._setPictures(pictures);
        }));
        conn.connect();
    },
    
    _processIndexSelect: function(e) {
        var newIndex = parseInt(this._pictureSelect.get("selection"));
        this._pictureContainer.set("type", newIndex < this._pictureIndex
                ? Extras.TransitionPane.TYPE_CAMERA_PAN_LEFT : Extras.TransitionPane.TYPE_CAMERA_PAN_RIGHT);
        this._pictureIndex = newIndex;
        this._updatePicture();
    },
    
    _processNext: function(e) {
        if (this._pictureIndex < this._pictures.length - 1) {
            this._pictureContainer.set("type", Extras.TransitionPane.TYPE_CAMERA_PAN_RIGHT);
            ++this._pictureIndex;
            this._updatePicture();
        }
    },
    
    _processPrevious: function(e) {
        if (this._pictureIndex > 0) {
            this._pictureContainer.set("type", Extras.TransitionPane.TYPE_CAMERA_PAN_LEFT);
            --this._pictureIndex;
            this._updatePicture();
        }
    },
    
    _processSelectAlbum: function(e) {
        this._loadAlbum(this._albumSelect.get("selectedId"));
    },
    
    _setPictures: function(pictures) {
        this._pictureContainer.set("type", Extras.TransitionPane.TYPE_FADE);
        this._pictures = pictures;
        this._pictureIndex = pictures.length > 0 ? 0 : -1;
        this._updatePicture();
        
        var selectItems = [];
        for (var i = 0; i < pictures.length; ++i) {
            selectItems.push(i + 1);
        }
        this._pictureSelect.set("items", selectItems);
    },

    _updatePicture: function() {
        this._pictureContainer.removeAll();
        if (this._pictureIndex == -1) {
            return;
        }

        this._previousButton.setEnabled(this._pictureIndex != 0);
        this._nextButton.setEnabled(this._pictureIndex != this._pictures.length - 1);
        
        this._pictureSelect.set("selection", this._pictureIndex);
        this._pictureContainer.add(new Echo.ContentPane({
            background: "#ffffff",
            backgroundImage: {
                url:  this._getPictureUrl(this._pictureIndex),
                repeat: 0,
                x: "50%",
                y: "50%"
            }
        }));
        this._captionLabel.set("text", this._pictures[this._pictureIndex].caption);
        
        if (this._pictureIndex < this._pictures.length - 1) {
            this._prefetch.set("image", this._getPictureUrl(this._pictureIndex + 1));
        }
    }
});

Album.Prefetch = Core.extend(Echo.Component, {
    componentType: "Album.Prefetch"
});

/**
 * Synchronization peer for HtmlLabel component.
 */
Album.PrefetchSync = Core.extend(Echo.Render.ComponentSync, {

    $load: function() {
        Echo.Render.registerPeer("Album.Prefetch", this);
    },

    _imgElement: null,

    renderAdd: function(update, parentElement) {
        this._imgElement = document.createElement("img");
        if (this.component.get("image")) {
            this._imgElement.src = this.component.get("image");
        }
        this._imgElement.style.cssText = "width:1px;height:1px;display:none;";
        parentElement.appendChild(this._imgElement);
    },

    renderDispose: function(update) {
        this._imgElement = null;
    },
    
    renderUpdate: function(update) {
        var element = this._imgElement;
        var containerElement = element.parentNode;
        this.renderDispose(update);
        containerElement.removeChild(element);
        this.renderAdd(update, containerElement);
        return false; // Child elements not supported: safe to return false.
    }
});
