
var GenreBox = Class.create({
   initialize: function(elementId,genres,selectedId,searchUrl,updateId) {
       this.genreParam    = 
       this.element       = $(elementId);
       this.genres        = genres;
       this.currentList   = genres;
       this.updateElement = $(updateId);
       this.searchUrl     = searchUrl;
       var box            = this.renderGenre(genres);
       this.element.appendChild(box);

       if ( selectedId ) {
           box.setStyle({'left': '-' + this.element.getWidth() + 'px'});
           var g = this.findGenre(selectedId);
           box            = this.renderGenre(g);
           this.element.appendChild(box);
           this.loadGenre(g);
       }
       new Effect.Morph(this.element, {style: { 'height': box.getHeight() + 'px'}, duration: 0.5, delay: 0.0 });
   },

    findGenre: function(selectedId) {
        if ( selectedId) {
            for ( var i = 0; i < this.genres.length; i++ ) {
                if ( this.genres[i].id == selectedId ) {
                    return this.genres[i];
                }
            }
            return this.genres;
        }
        else {
            return this.genres;
        }
    },

    loadGenre: function(genre) {
        if ( genre.id ) {
            if ( !this.updateElement ) {
                document.location.href = this.searchUrl + genre.id;
                return false;
            }
            else {
                new Ajax.Updater(this.updateElement,this.searchUrl + genre.id);
            }
        }
        return true;
    },

    showGenre: function(genre) {
        if ( !this.loadGenre(genre) ) return;

        if ( genre == this.currentList ) return;


        if ( genre.subGenres == null || genre.subGenres.length < 1 ) return;

        var box = this.renderGenre(genre);

        var lastBox = this.element.childElements().last();
        if ( lastBox != null ) {
            var w = this.element.getWidth();
            box.setStyle({'left': w + 'px'});
            this.element.appendChild(box);
            var lastH    = lastBox.getHeight();
            var currentH = box.getHeight();
            var delayT = 0.0;

            if ( currentH > lastH ) {
              delayT = 0.2;
              new Effect.Morph(this.element, {style: { 'height': currentH + 'px'}, duration: 0.2, delay: 0.0 });
            }
            new Effect.Morph(lastBox, { style: {'left': '-' + w + 'px' }, duration:1.0, delay: delayT });
            new Effect.Morph(box, { style: {'left': '0px' }, duration:1.0, delay: delayT });
            if ( lastH > currentH ) {
              new Effect.Morph(this.element, {style: { 'height': currentH + 'px'}, duration: 0.2, delay: 0.7 });
            }
        }
        else {
            this.element.appendChild(box);
            this.element.setStyle({'height': box.getHeight() + 'px', 'width': box.getWidth() + 'px'});
        }
    },

    renderGenre: function(genre) {
        var box  = new Element('div',{'class':'genre_box'})
        var iter = genre;
        this.currentList = genre;
        if ( genre != this.genres ) {
            iter = genre.subGenres;
            var backBtn = new Element('a', { id: 'genre_box-back'}).update('< Back');
            backBtn.observe('click', this.backClick.bind(this));

            box.appendChild(backBtn);

            var head = new Element('a',{id: 'genre_box-selected', name: genre.name}).update(genre.name)
            head.observe('click', this.genreClick.bind(this))
            box.appendChild(head);
        }

        for ( var i = 0; i < iter.length; i++ ) {
            var current = iter[i];
            var body = current.name;

            if ( current.subGenres != null && current.subGenres.length > 0 ) {
                body = '<span style="float: right; margin-right: 10px;">&gt;</span>' + body;
            }
            var entryLink = new Element('a',{'class':'genre_box-entry', name:current.name}).update(body);
            entryLink.observe('click', this.genreClick.bind(this))
            box.appendChild(entryLink);
        }
        return box;
    },

    genreClick: function(event) {
        var tgt = event.element();
        if ( tgt.tagName.toLowerCase() != 'a' ) tgt = tgt.up('a');
        var name = tgt.name;

        var list = this.currentList;
        if ( list.name && list.name == name ) {
          this.showGenre(list);
          return;
        }
      
        if ( list.id ) list = list.subGenres

        for ( var i = 0; i < list.length; i++ ) {
            if ( name == list[i].name ) {
                this.showGenre(list[i]);
                break;
            }
        }
    },

    reset: function() {
        this.backClick();
    },

    backClick: function() {
        var boxElms = this.element.childElements();
        if ( boxElms.size() > 1 ) {
            var toRemove = boxElms.last();
            var toShow   = toRemove.previous()
            var w        = this.element.getWidth();
            var removeH  = toRemove.getHeight();
            var showH    = toShow.getHeight();
            var delayT   = 0.0;

            if ( showH > removeH ) {
              delayT = 0.2;
              new Effect.Morph(this.element, {style: { 'height': showH + 'px'}, duration: 0.2, delay: 0.0 });
            }

            new Effect.Morph(toRemove, { style: {'left': w + 'px' }, duration:1.0, delay: delayT });
            new Effect.Morph(toShow, { style: {'left': '0px' }, duration:1.0, delay: delayT });

            if ( removeH > showH ) {
              new Effect.Morph(this.element, {style: { 'height': showH + 'px'}, duration: 0.2, delay: 0.7 });
            }
            //TODO: Find previouse list if there are more than 2 levels of genres
            this.currentList = this.genres;
            setTimeout(this.removeLast.bind(this),1000);
        }
    },

    removeLast: function() {
        this.element.childElements().last().remove();
    }

});