function $e(n) { return document.getElementById(n); }
var Album = new (function() {
    var my = this;

    window.isIE = navigator.appVersion.indexOf("MSIE")>0 ?
        parseFloat(navigator.appVersion.split(" ")[3])
        : false;
    window.isSafari = !isIE && navigator.vendor.indexOf("Apple") > -1 ?
        parseFloat(navigator.appVersion.split(" ")[12].split("/")[1])
        : false;
    window.isNS = !(window.isIE || window.isSafari) ?
        navigator.buildID
        : false;

    this.initialize = function() {
        this.folders = new Navigator().initialize($e("folders"));
        this.viewer = new Viewer().initialize($e("viewer"));
        this.preview = new Scroller().initialize($e("preview"));
        this.tagger = new Tagger().initialize($e("tagger"));
        this.searcher = new SearchTab().initialize($e("searcher-body"));
        
        Event.observe(window, "resize", this.initSizes);
        /* Fix Mozilla sticky-drag bug */
        //if (window.isNS && window.isNS < 2007120000) {
        /*
        if (window.isNS) {
            Event.observe(document, "mouseout",
            function (evt) {
                if (evt.clientX < 0 || evt.clientX > window.innerWidth ||
                    evt.clientY < 0 || evt.clientY > window.innerHeight) {
                    my.folders.stopMove();
                    my.tagger.stopMove();
                    my.preview.stopDrag();
                }
            });
        }
        */
        
        this.initSizes();
        //this.preview.toggleScroll();
        
        /*
         * Parse URL for auto-loading
         */
        var path = window.location.search.split(/path=/)[1];
        if (path && path.length > 0) {
            this.folders.isQueueing = true;
            this.folders.loadResource(decodeURIComponent(path));
        }

        this.loadCustomizations();
        this.origTitle = document.title;
        this.loadTagService();
        return this;
    }

    this.customize = function() { }

    this.loadCustomizations = function() {
        var my = this;
        this.loadScript("scripts/custom.js",
        function() {
            my.customize();
        });
    }

    this.loadTagService = function() {
        this.loadScript("tags/dwr/interface/TagService.js",
        function() {
            if (typeof(TagService) != "undefined") {
                $e("searcher").style.visibility = "visible";
                dwr.engine.setErrorHandler(null);

                // Parse URL for auto-loading
                var tag = window.location.search.split(/tag=/)[1];
                if (tag && tag.length > 0) {
                    my.folders.loadTag(decodeURIComponent(tag));
                }
            }
        });
    }

    this.loadScript = function(path, handler) {
        var s = document.createElement("script");
        s.type = "text/javascript";
        s.src = path;
        document.getElementsByTagName("head")[0].appendChild(s);
        s.onreadystatechange = s.onload = handler;
    }

    this.initSizes = function() {
        /*
         * Resize preview to fit screen
         */
        var vc = $e("viewer-content");
        var f = Album.folders.content;
        var maxheight = (document.body.clientHeight - $e("preview").offsetHeight - 24);
        //if (maxheight > 480) maxheight = 480;
        vc.style.height = maxheight + "px";
        f.style.height = (maxheight - 35) + "px";
    }
    this.getTarget = function(evt) {
        return evt.target ? evt.target : evt.srcElement;
    }
    this.getCoords = function(elem) {
        var _x = 0;
        var _y = 0;

        for (; elem.offsetParent; elem = elem.offsetParent) {
            _x += elem.offsetLeft;
            _y += elem.offsetTop;
        }
        return {x:_x, y:_y};
    }
    /*
    this.bind = function(pub, pm, sub) {
        var orig = pub[pm];
        pub[pm] = function() {
            orig(arguments);
            sub(arguments);
        }
    }
    */
    this.getThumbPath = function(path) {
        if (!path.match(/^thumbs\//)) return "thumbs/"+path;
        return path;
    }
    this.getActualPath = function(path) {
        //if (path.match(/^thumbs\//)) return path.substring(7);
        //return path;
        return this.getThumbPath(path).substring(7);
    }
    this.getThumbFile = function(path) {
        var dirs = path.split("/");
        var file = dirs[dirs.length-1];
        if (file.match(/\.jpg$/i)) {
            file = "thumb:"+file;
            dirs[dirs.length-1] = file;
            return this.getThumbPath(dirs.join("/"));
        } else if(file.match(/\.flv$/i)) {
            var extAt = file.lastIndexOf(".");
            file = "thumb:"+file.substring(0, extAt)+".jpg";
            dirs[dirs.length-1] = file;
            return this.getThumbPath(dirs.join("/"));
        } else {
            return "images/folder.gif";
        }
    }

    this.fullSize = function() {
    };

    this.saveHistory = function(path) {
        $e("history").contentWindow.location.search = path;
    }

    this.restoreHistory = function(path) {
        if (this.viewer) this.viewer.show(decodeURIComponent(path));
    }
})();

/*
 * Class declarations
 */
function NodeWrapper() {
    var my = this;

    this.initialize = function(comp) {
        this.element = comp;
        if (!this.element) return;
        this.titleBar = this.getTitleBar();
        this.content = this.getContent();

        if (typeof this.constructor == "function") this.constructor();
        return this;
    }
    this.getElementsByClass = function(className) {
        var elems = this.element.getElementsByTagName("*");
        var children = new Array();
        for (var i = 0; i < elems.length; i++) {
            if (elems[i].className.match("\\b" + className + "\\b")) {
                children.push(elems[i]);
            }
        }
        return children;
    }
    this.getTitleBar = function() {
        return this.getElementsByClass("titletext")[0];
    }
    this.getContent = function() {
        return this.getElementsByClass("content")[0];
    }
}

Frame.prototype = new NodeWrapper();
function Frame() {
    var my = this;

    this.constructor = function() {
        this.titleBar.onmousedown =
        this.titleBar.onmousemove =
        function() { return false; };
        Event.observe(this.titleBar, "mousedown", this.startMove);
        Event.observe(document, "mousemove", this.doMove);
        Event.observe(document, "mouseup", this.stopMove);
        var closer = this.getElementsByClass("closer")[0];
        if (closer) Event.observe(closer, "click", this.close);
    }

    this.startMove = function(evt) {
        my.isMoving = true;
        var coords = Album.getCoords(my.element);
        my.dragOffset = { x : evt.clientX - coords.x, y : evt.clientY - coords.y }
        //Element.addClassName(my.element, "move");
        document.onselectstart = function() { return false; }
    }

    this.doMove = function(evt) {
        if (!my.isMoving) return;
        Element.addClassName(my.element, "move");
        if (window.isNS || evt.clientY > 0 && evt.clientY < document.body.clientHeight)
            my.element.style.top = (evt.clientY - my.dragOffset.y) + "px";

        if (window.isNS || evt.clientX > 0 && evt.clientX < document.body.clientWidth)
            my.element.style.left = (evt.clientX - my.dragOffset.x) + "px";

    }

    this.stopMove = function() {
        my.isMoving = false;
        Element.removeClassName(my.element, "move");
        document.onselectstart = null;
    }
    this.close = function() {
        my.element.style.display = "none";
    }
    this.show = function(evt) {
        if (evt) {
            my.element.style.left = (evt.clientX - 10) + "px";
            my.element.style.top = Math.abs(evt.clientY - 10) + "px";
        }
        my.element.style.display = "block";
    }
    this.isShown = function() {
        return my.element.style.display == "block";
    }
}

Tagger.prototype = new NodeWrapper();
function Tagger() {
    var my = this;
    this.resource = {};

    this.constructor = function() {
        this.frame = new Frame().initialize(this.element);
    }
    
    this.showLink = function(path) {
        var input = $e("linker-text");
        var colon = window.location.port.length > 0 ? ":" : "";
        path = path.match("/") ?  "?path=" + encodeURIComponent(path) : "";
        input.value = window.location.protocol + "//" +
            window.location.hostname + colon + window.location.port +
            window.location.pathname + path;
        input.focus();
        input.select();
    }

    this.getTags = function(path) {
        $e("tags-text").value = "";
        my.resource = {uri:path};
        TagService.getResource(my.resource, function(r) {
            my.resource = r;
            var tags = r['tags'];
            var t = [];
            for (var i=0; i < tags.length; i++) {
                t.push(tags[i].text);
            }
            $e("tags-text").value = t.join(" ");
        });
    }

    this.saveTags = function(form) {
        var tags = form.tags.value.split(" ");
        var t = [];
        for (var i=0; i < tags.length; i++) {
            if (tags[i].length > 0) t.push({text:tags[i].toLowerCase()});
        }
        my.resource.tags = t;

        TagService.saveResource(my.resource, function() {
            alert('saved');
            my.close();
        });
    }

    this.show = function(evt, path) {
        this.frame.show(evt);
        this.showLink(path);
        this.getTags(path);
    }

    this.update = function(path) {
        if (this.frame.isShown()) {
            this.show(false, path);
        }
    }

    this.close = function() { this.frame.close(); }
    this.stopMove = function() { this.frame.stopMove(); }
}

Viewer.prototype = new NodeWrapper();
function Viewer() {
    var my = this;

    this.constructor = function() {
        my.titleText = $e("viewer-title");

        Event.observe(my.titleText, "click", function(evt) {
            Album.tagger.show(evt, my.titleText.firstChild.nodeValue);
        });
    }

    this.show = function(path) {
        if (!path || path.length == 0) {
            my.titleText.innerHTML = my.content.innerHTML = "";
            document.title = Album.origTitle;
            return;
        } else {
            path = Album.getActualPath(path);
        }
        if (my.titleText.innerHTML == path) return;


        my.titleText.innerHTML = path;
        document.title = Album.origTitle + " (" + path.substring(path.lastIndexOf("/")+1) + ")";
        if (path.match(/\.flv$/)) {
            this.showMovie(path);
            this.element.className = "viewer";
        } else {
            this.showImage(path);
            this.element.className = "viewer image";
        }

        Album.tagger.update(path);
    }

    this.showImage = function(path) {
        var l = $e("loading");
        l.style.display = "block";
        my.content.innerHTML ="<img src=\""+Album.getThumbPath(path)+"\"/>";
        //my.content.innerHTML ="<img height='"+my.content.clientHeight+"' src=\""+Album.getThumbPath(path)+"\"/>";

        Event.observe(my.content.firstChild, "load", function() {
            l.style.display = "";
        });
    }

    this.showMovie = function(path) {
        var mHeight = my.content.clientHeight;
        var mWidth = parseInt(mHeight * 1.3333);
        var vars = "flvpVideoSource="+Album.getThumbPath(path)+"&flvpWidth="+mWidth+"&flvpHeight="+mHeight;
        $e("viewer-content").innerHTML =
        //'<object data="FlvPlayer.swf" type="application/x-shockwave-flash" style="visibility:visible" width="'+mWidth+'" height="'+mHeight+'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000">'+
        '<object data="FlvPlayer.swf" type="application/x-shockwave-flash" style="visibility:visible" width="'+mWidth+'" height="'+mHeight+'">'+
        '<param name="bgcolor" value="FFFFFF"/>'+
        '<param name="menu" value="true"/>'+
        '<param name="allowfullscreen" value="true"/>'+
        '<param name="wmode" value="transparent"/>'+
        '<param name="flashvars" value="'+vars+'"/>'+
        '</object>';
        /*
        : "<embed width=\""+mWidth+"\" height=\""+mHeight+"\""+
        " bgcolor=\"#FFF\""+
        " type=\"application/x-shockwave-flash\""+
        " pluginspage=\""+pluginsPage+"\""+
        " wmode=\"transparent\""+
        " allowscriptaccess=\"always\""+
        " allowfullscreen=\"true\""+
        " flashvars=\""+vars+"\""+
        " src=\"flvplayer.swf\"/>"
        );
        */
    }

    this.showFullImage = function() {
        window.open(this.titleText.innerHTML);
    };
}

Scroller.prototype = new NodeWrapper();
function Scroller(comp) {
    var my = this;

    this.constructor = function() {
        this.titleText = $e("preview-title");
        this.coords = Album.getCoords(my.element);
        this.canvas = my.getElementsByClass("canvas")[0];

        this.content.onmousedown =
        this.content.onmousemove =
        function() { return false; };
        Event.observe(this.content, "mousedown", this.startDrag);
        Event.observe(document, "mousemove", this.dragHandler);
        //Event.observe(document, "mousemove", this.doDrag);
        //Event.observe(document, "mousemove", this.canvasFiller);
        Event.observe(document, "mouseup", this.stopDrag);
    
        Event.observe(my.titleText, "click", function(evt) {
            Album.tagger.show(evt, my.titleText.firstChild.nodeValue);
        });
        Event.observe(window, "resize", function() {
            my.coords = Album.getCoords(my.element);
        });
    }

    this.dragHandler = function(evt) {
        if (!my.isDragging) return;
        my.doDrag(evt);
        my.canvasFiller(evt);
    }

    this.getPreferScroll = function() {
        var scroll = false;
        var splits = document.cookie.split(";");
        for (var i = 0; i < splits.length; i++) {
            if (splits[i].match(/\bAlbum\.scroll=/)) {
                scroll = splits[i].split("=")[1];
            }
        }
        return scroll == "true" ? true : false;
    }
    
    this.setPreferScroll = function(scroll) {
        var domain = document.location.hostname;
        document.cookie = "Album.scroll=" + scroll + "; domain=" + domain + "; path=/; expires=Tue, Feb 14, 2017 2:52:54 PM";
    }

    this.startDrag = function(evt) {
        my.clickOffset = evt ? evt.clientX : 0;

        if (my.isScrollable) return;
        my.isDragging = true;

        my.dragOffset = evt ? evt.clientX - my.coords.x - my.canvas.offsetLeft : 0;
        my.canvas.previousX = my.canvas.offsetLeft;
        Element.addClassName(my.canvas, "drag");
        if (window.isIE) my.canvas.style.cursor = "images/grabbing.cur";
    }
    
    this.stopDrag = function() {
        if (!my.isDragging) return;
        my.isDragging = false;
        Element.removeClassName(my.canvas, "drag");
        if (window.isIE) my.canvas.style.cursor = "";
        my.dragOffset = 0;

        // Scroll canvas back into view if moved beyond extents
        var beyondRight = my.canvas.offsetLeft + my.canvas.offsetWidth;
        if (my.canvas.offsetWidth < my.content.clientWidth || my.canvas.offsetLeft > 0) {
            my.autoScroll(-1*my.canvas.offsetLeft);
        } else if (beyondRight < my.content.clientWidth) {
            var diff = my.content.clientWidth - beyondRight;
            // compensate for border spacing
            if (Math.abs(diff) > 2)
                my.autoScroll(my.content.clientWidth - beyondRight);
        }
    }
    
    this.doDrag = function(evt) {
        my.scrollCanvas(evt.clientX);
    }

    this.scrollCanvas = function(offset) {
        var delta = offset - my.dragOffset;

        my.canvas.style.left = delta + "px";
        my.canvas.previousX = delta;
    }

    this.autoScroll = function(offset) {
        //this.startDrag();
        this.scrollCanvas(this.canvas.offsetLeft+offset);
        //this.stopDrag();
    }

    this.scrollTo = function(image) {
        if (!my.images || my.images.length == 0) {
            setTimeout(function() { my.scrollTo(image); }, 500);
            return;
        }

        var paths = image.split("/");
        var file = paths.pop();
        if (file.match(/flv$/)) {
            file = file.substring(0, file.lastIndexOf("."))+".jpg";
        }
        paths.push("thumb:"+file);

        var thumb = Album.getThumbPath(paths.join("/"));
        if (my.isScrollable) {
        } else {
            //if (my.images.length > my.imageIndex && !my.appendedImages[thumb]) {
            //if (my.images.length > my.imageIndex && my.canvas.innerHTML.indexOf(image)<0) {
            if (false) {
                my.startDrag();
                my.autoScroll(-50);
                my.stopDrag();
                setTimeout(function() {my.scrollTo(image);}, 10);
            } else {
                my.startDrag();
                my.autoScroll(-50);
                my.stopDrag();
                Album.viewer.show(image);
                Album.saveHistory(image);
            }
        }
    }

    this.toggleScroll = function(target) { if (target) {
            my.setPreferScroll(target.checked);
        } else {
            target = $e("toggleScroll");
            target.checked = my.getPreferScroll();
        }

        var leftscroll = my.content.scrollLeft;
        my.content.scrollLeft = parseInt(my.canvas.style.left) * -1;
        my.canvas.style.left = parseInt(leftscroll) * -1;
        my.isScrollable = target.checked;
        if (my.isScrollable) {
            my.content.style.overflowX = "auto";
            while (my.imageIndex < my.images.length) {
                my.appendImage();
            }
        } else {
            my.content.style.overflowX = "hidden";
        }
    }

    this.loadThumbs = function(dir, images) {
        if (dir == my.titleText.firstChild.nodeValue) return;
        my.images = images;
        //my.content.style.width = "1px";
        my.canvas.style.width =
        my.canvas.style.left =
        my.content.scrollLeft =
        my.imageIndex = 0;
        //my.appendedImages = [];
        my.canvas.innerHTML    = "";
        my.titleText.innerHTML = Album.getActualPath(dir);
    
        if (my.images.length < 1) return;
        for (var i = 0, accum = 0; i < my.images.length; i++) {
            if (my.isScrollable || accum < my.content.clientWidth) {
                accum += my.images[i].w;
                my.appendImage();
            }
            else break;
        }

        Album.tagger.update(dir);
    }

    this.canvasFiller = function(evt) {
        var delta = evt.clientX - my.dragOffset;
    
        if (delta <= my.canvas.previousX) {
            /*
              * Load new image if moved beyond viewable area
              */
            if (my.canvas.offsetWidth + my.canvas.offsetLeft <
                my.content.clientWidth) {
                if (my.imageIndex < my.images.length) {
                    my.appendImage();
                }
            }
        }
    }

    this.appendImage = function() {
        var tile = document.createElement("a");
        tile.className = "tile";
        var image = document.createElement("img");
        var imgMeta = my.images[my.imageIndex++];
        if (typeof imgMeta == "object" && imgMeta.w > 0) {
            tile.href = "";
            tile.style.width = imgMeta.w + "px";
            tile.style.height = imgMeta.h + "px";
            tile.appendChild(image);
        
            //my.appendedImages[imgMeta.tn] = true;
            image.src = imgMeta.tn;
            // set width by meta since offsetWidth isn't set until image loaded
            my.canvas.style.width = my.canvas.offsetWidth + imgMeta.w + 1 + "px";
            my.canvas.appendChild(tile);

            /* Create filename overlay */
            var nameSplitAt = imgMeta.lg.lastIndexOf(":");
            if (nameSplitAt < 0) nameSplitAt = imgMeta.lg.lastIndexOf("/");
            var basename = imgMeta.lg.substring(nameSplitAt+1);
            tile.appendChild(my.createOverlay(basename));

            tile.onclick = function() { return false; }
            Event.observe(tile, "click", function(event) {
                if (event.clientX == my.clickOffset) {
                    Album.viewer.show(imgMeta.lg);
                    Album.saveHistory(imgMeta.lg);
                }
                return false;
            });
        }
    }

    this.createOverlay = function(text) {
        var overlay = document.createElement("div");
        overlay.className = "overlay";

        /*
        Event.observe(overlay, "mouseover", function() {
            overlay.style.display = "";
        });
        Event.observe(overlay, "mouseout", function() {
            overlay.style.display = "none";
        });

        overlay.text = document.createElement("div");
        overlay.text.innerHTML = text;
        overlay.appendChild(overlay.text);
        */
        overlay.innerHTML = text;
        return overlay;
    }
    
}

Navigator.prototype = new NodeWrapper();
function Navigator() {
    var my = this;

    this.tabs = {};

    this.constructor = function() {
        this.frame = new Frame().initialize(this.element);
        /*
         * Find tabs and add click event handlers
         */
        var tabs = this.getElementsByClass("tabheader");
        for (var i = 0; i < tabs.length; i++) {
            Event.observe(tabs[i], "click", function(evt) {
                my.showTab(Album.getTarget(evt));
            });
        }
    }

    //this.stopMove = function() { this.frame.stopMove(); }

    this.isQueueing = false;
    this.loadTab = function(tabHeader) {
        var id = tabHeader.id;
        var tab = this.tabs[id];
        if (!tab) {
            var jsClass = $e(id+"-body").getAttribute("jsClass");
            tab = this.tabs[id] = eval("new "+jsClass+"()");
            tab.initialize($e(id+"-body"));
            if (!this.isQueueing) {
                tab.loadManifest(
                    tab.element,
                    tabHeader.getAttribute("root"),
                    function() {}
                );
            }
        }
        return tab;
    }

    this.showTab = function(tabHeader) {
        var headers = document.getElementsByClassName("tabheader");
        for (var i = 0; i < headers.length; i++) {
            Element.removeClassName(headers[i], "active");
        }
        Element.addClassName(tabHeader, "active");

        var tab = this.loadTab(tabHeader);

        for (var t in this.tabs) {
            Element.removeClassName(this.tabs[t].element, "active");
        }

        Element.addClassName(tab.element, "active");
        return tab;
    }

    this.loadResource = function(path) {
        var headers = document.getElementsByClassName("tabheader");
        var tab = false;
        for (var i = 0; i < headers.length; i++) {
            if (path.search(headers[i].getAttribute("root")) == 0) {
                this.isQueueing = true;
                this.showTab(headers[i]).queue(null, path);
                this.isQueueing = false;
                break;
            }
        }
    }

    this.loadTag = function(tag) {
        this.showTab($e("searcher"));
        var form = document.forms["tag-form"];
        form.elements['query'].value = tag;
        Album.searcher.search(tag);
    }

    this.stopMove = function() { this.frame.stopMove(); }

}

Tab.prototype = new NodeWrapper();
function Tab() {
    var my = this;

    this.loadManifest = function(target, dir, callback) {
        new Ajax.Request(Album.getThumbPath(dir + "/manifest.json"), {
            method: "GET",
            onComplete: function(transport) {
                eval("var obj=" + transport.responseText);
                my.directories = obj.directories;
                my.buildDirectory(target);
                if (typeof callback == "function") callback(dir);
                else Album.preview.loadThumbs(dir, obj.images);
            }
        });
    }

    this.queue = function(target, path) {
        this.queuedPath = [];
        this.element.innerHTML = "";
        this.queuedLoad(target, path);
    }
    this.queuedLoad = function(target, path) {
        if (!target) target = this.element;
        var dirs = path.split("/");
        var next = dirs.shift();

        var spans = target.getElementsByTagName("span");
        for (var i=0; i < spans.length; i++) {
            if (spans[i].firstChild.nodeValue == next) {
                target = spans[i].parentNode;
                //Element.addClassName(target, "highlight");
                //Element.removeClassName(target.parentNode.parentNode, "highlight");
                target.firstChild.className = "highlight";
                target.parentNode.parentNode.firstChild.className = "";
                // scroll element into view
                this.element.scrollTop = target.offsetTop;
                break;
            }
        }

        if (next) {
            this.queuedPath.push(next);
            if (next.match(/\.jpg$/ig) || next.match(/\.flv$/ig)) {
                var image = this.queuedPath.join("/");
                Album.preview.scrollTo(image);
                this.queuedPath.pop();
                dirs = [];
            }
            var requeue = function(dir) {
                my.queuedLoad(target, dirs.join("/"));
            }
            if (dirs.length == 0) {
                requeue = null;
            }
            this.loadManifest(target, this.queuedPath.join("/"), requeue);
            this.element.scrollTo(0, target.offsetTop);
        }
    }

    this.toggleBranch = function(target, dir) {
        var all = my.getElementsByClass("highlight");
        for (var i = 0; i < all.length; i++) {
            //Element.removeClassName(all[i], "highlight");
            all[i].className = "";
        }
        var parent = target.parentNode;
        if (parent.childNodes.length > 1) {
            parent.removeChild(parent.childNodes[1]);
            parent = null;
        }
        my.loadManifest(parent, dir);
        target.className = "highlight";
    }

    this.buildDirectory = function(target) {
        if (my.directories.length > 0) {
            // TODO: remove any 2nd-offset child nodes (UL's) for the time being
            // queuedLoad is requeueing the call to loadManifest after the last
            // entry
            if (target.childNodes[1]) target.removeChild(target.childNodes[1]);
            var dirs = document.createElement("ul");
            for (var d = 0; d < my.directories.length; d++) {
                var dir = my.directories[d];
                var lastSlash = dir.lastIndexOf("/");
                if (lastSlash > 0) {
                    dir = dir.substring(lastSlash + 1);
                }
                var li = document.createElement("li");
                var span = document.createElement("span");
                span.innerHTML = dir;
                span.directory = my.directories[d];
                Event.observe(span, "click", function(evt) {
                    my.toggleBranch(Album.getTarget(evt), Album.getTarget(evt).directory);
                });

                li.appendChild(span);
                dirs.appendChild(li);
            }
            target.appendChild(this.fold(dirs));
        }
    }

    this.fold = function(ul) {
        /*
        if (ul.childNodes.length > 40) {
            var fold = ul.childNodes.length-20;
            var li = document.createElement("li");
            li.innerHTML = ". . .";
            for (var i=0; i<fold; i++) {
                ul.childNodes[i].style.display="none";
            }
            ul.insertBefore(li, ul.childNodes[0]);
        }
        */
        return ul;
    }
}

SearchTab.prototype = new Tab();
function SearchTab() {
    var my = this;

    this.constructor = function() {
        this.subcontent = this.getElementsByClass("sub-content")[0];
        this.recentcontent = this.getElementsByClass("recent-content")[0];
    }

    /*
     * Override Tab's load.. to get recent tags
     */
    this.loadManifest = function() {
        TagService.getRecentTags(0, function(recentTags) {
            var tl = [];
            for (var i=0; i < recentTags.length; i++) {
                var rt = recentTags[i];
                //var fontSize = rt.count > 10 ? rt.count / 10 : 1+"."+rt.count;
                var fontSize = (10*rt.count) + 100;
                fontSize = fontSize < 200 ? fontSize : 200;
                tl.push(
                "<a href style='font-size:"+fontSize+"%' onclick=\"Album.searcher.tagSearch('"+rt.tag.text+"');return false;\">"+rt.tag.text+"</a>,"
                );
            }
            my.recentcontent.innerHTML = tl.join(" ").replace(/,$/, '');
        });
    }

    this.tagSearch = function(query) {
        $e("tag-query").value = query;
        this.search(query);
    }

    this.search = function(query) {
        TagService.findResources(query, function(resources) {
            var buff = ["<td><b>Nothing found for '"+query+"'</b></td>"];
            resources = resources.reverse();
            for (var i=0,len=resources.length; i < len; i++) {
                var resource = resources[i],
                odd = i % 2 ? "class='odd'" : "",
                title = [];
                for (var t=0; t < resource.tags.length; t++) {
                    title.push(resource.tags[t].text);
                }

                var img=[
                    '<td><img title="',
                    title.join(' '),
                    '" src="',
                    Album.getThumbFile(resource.uri),
                    '"/></td>'].join('');
                var row=[
                    '<tr ',
                    odd,
                    ' onclick="Album.folders.loadResource(this.childNodes[1].firstChild.nodeValue)">',
                    img,
                    '<td>',
                    resource.uri,
                    '</td></tr>'].join('');
                buff[i] = row;
            }
            my.subcontent.innerHTML = "<table>"+buff.join("")+"</table>";
        });
    }
}

