var Module = Class.create();
Module.prototype = {
	id: '',
	name: '',
	buckets: [],
  currentBucket: '',
  playlistId: null,

	initialize: function( s_id, s_name, a_buckets ){
		this.id = s_id;
		this.name = s_name;
		for( var i=0; i<a_buckets.length; i++ ){
			this.addBucket( a_buckets[i] );
		}
	},

	show: function( bucketId, playlistId ) {
    // persist the playlist id to use for subsequent buckets
    this.playlistId = playlistId;
		document.title = this.name;
		document.body.id = this.id;
    heading = $('moduleTitle');
    heading.update( this.name + ': ' );
    this.buildNavigation();
    // figure out what bucket to show
    var bucket = this.getBucket( bucketId );
    if( !bucket ){
      alert( 'invalid bucket' );
    }
    else {
      this.showBucket( bucket );
    }
	},
  
  /* 
   * It may make sense to move some of these functions
   * up a level to a Presentation class.
   */
	
	handlePrimaryNavClick: function( e ){
    li = Event.findElement( e, 'li' );
    id = li.id;
    idx = id.indexOf('nav_');
    if( idx > -1 ){
      id = id.substring( idx + 4 );
      bucket = this.getBucket( id );
      if( bucket ){
        this.showBucket( bucket );
      }
    }
	},
	
  
  handleControlNavClick: function( e ){
    li = Event.findElement( e, 'li' );
    id = li.id;
    if( id ){
      switch( id ){
        case 'play':
          this.currentBucket.currentPlaylist.changePlayPauseTo( 'pause' );
          break;
        case 'pause':
          this.currentBucket.currentPlaylist.changePlayPauseTo( 'play' );
          break;
        case 'back':
          this.goPrevious( e );
          break;
        case 'forward':
          this.goNext( e );
          break;
        default : alert( 'invalid control: ' + id );
      }
    }
  },
  
  goPrevious: function( e ){
    if( !this.currentBucket.currentPlaylist || 
        !this.currentBucket.currentPlaylist.showPreviousTopic() ){
      if( !this.showPreviousBucket() ){
        // go home
        if( e ){
          Event.stop( e );
        }
        var currentLocation = top.document.location.href;
        var idx = currentLocation.indexOf( '/presentation.' );
        currentLocation = currentLocation.substring( 0, idx + 1 );
        currentLocation = currentLocation + 'modules/' + this.id +  '/index.htm';
        top.document.location.href = currentLocation;
      }
    }
  },
  
  goNext: function( e ){
    if( !this.currentBucket.currentPlaylist || 
        !this.currentBucket.currentPlaylist.showNextTopic() ){
      if( !this.showNextBucket() ){
        // go home
				if( e ){
				  Event.stop( e );
				}
				var currentLocation = top.document.location.href;
				var idx = currentLocation.indexOf( '/presentation.' );
				currentLocation = currentLocation.substring( 0, idx + 1 );
				currentLocation = currentLocation + 'modules/' + this.id +  '/index.htm';
        top.document.location.href = currentLocation;
      }
    }
  },
  
	addBucket: function( o_bucket ){
		this.buckets.push( o_bucket ); 
	},
	
	// TODO: generalize this function so it deletes arbitrary buckets
	deleteBucket: function( o_bucket ){
		this.buckets.splice( 0 , 1 ); 
	},
	
	getBucket: function( id ){
		return this.buckets.find( function(bucket){
			return( bucket.id == id );
		});
	},

  getNextBucket: function( ){
    id = this.currentBucket.id;
    idx = this.getBucketIndex( id );
    idx = idx + 1;
    if( idx < this.buckets.length ){
      return this.buckets[idx];
    }
    else {
      return null;
    }
  },
  
  getPreviousBucket: function( ){
    id = this.currentBucket.id;
    idx = this.getBucketIndex( id );
    idx = idx - 1;
    if( idx > -1 ){
      return this.buckets[idx];
    }
    else {
      return null;
    }    
  },
  
  showNextBucket: function( ){
    bucket = this.getNextBucket();
    if( bucket ){
      this.showBucket( bucket );
      return true;
    }
    else {
      return false;
    }
  },
  
  showPreviousBucket: function( ){
    bucket = this.getPreviousBucket();
    if( bucket ){
      this.showBucket( bucket );
      return true;
    }
    else {
      return false;
    }
  },
  
  showBucket: function( bucket ){
    if( bucket ){
      this.currentBucket = bucket;
      this.currentBucket.show( this.playlistId );
    }
  },
  
  getBucketIndex: function( id ){
    rv = null;
    if( this.buckets ){
      for( var i=0; i<this.buckets.length; i++ ){
        bucket = this.buckets[i];
        if( bucket.id == id ){
          rv = i;
          break;
        }
      }
    } 
    return rv;  
  },
  
  getAllTopics: function( playlist_id ){
    var all = new Hash(); 
    for( var i=0; i<this.buckets.length; i++ ){
      var bucket = this.buckets[i];
      if( bucket && bucket.playlists ){
        var playlist = bucket.getPlaylist( playlist_id );
        for( var n=0; n<playlist.topics.length; n++ ){
          var topic = playlist.topics[n];
					// XXX: hackish? Add the bucket name and id to the topic object
					// so that we can break up the list in the presentation builder
					if( !all[topic.id] ){
					  topic.bucket_name = bucket.name
					  topic.bucket_id = bucket.id
						all[topic.id] = topic;
					}
        }
      }
    }
		rv = all.values();
		/*
		rv.sort(function(a,b){
			if( a.bucket_name == b.bucket_name ){
				if( a.name == b.name ){
					r = 0;
				}
				else {
				  r = (a.name > b.name)?1:-1;
				}
			}
			else {
				r = (a.bucket_name > b.bucket_name)?1:-1;
			}
			return r;
		});
		*/
		return rv;
  },
	
	getTopic: function( id ){
		var all_topics = this.getAllTopics( 'default' );
		var rv = null;
		for( var i=0; i<all_topics.length; i++ ){
			topic = all_topics[i];
			if( topic.id == id ){
				rv = topic;
				break;
			}
		} 
		return rv;
	},
  
  buildNavigation: function( ){
    // <a href="#">Take Charge</a><span class="navSubtitle">Manage Your Account</span>
    var primaryUL = $('navPrimaryUL');
    Element.extend( primaryUL );
    // whack any children
    var children = primaryUL.immediateDescendants();
    for( var i=0; i<children.length; i++ ){
      id = children[i].id;
      if( id ){
        new Effect.Fade( id );
      }
      Element.remove( children[i] );
    }
    // append new children
    homeLI = document.createElement('li');
    Element.extend( homeLI );
    homeLI.addClassName( 'navHome' );
    homeLI.setAttribute( 'id', 'nav_home' );
    homeLI.addClassName( 'first' );
    homeA = document.createElement('a');
    homeA.setAttribute( 'href', 'modules/' + this.id +  '/index.htm' );
    homeA.innerHTML = 'Home';
    homeLI.appendChild( homeA );
    primaryUL.appendChild( homeLI );
		
    for( var i=0; i<this.buckets.length; i++ ){
      var bucket = this.buckets[i];
      var newLI = document.createElement( 'li' );
      Element.extend( newLI );
      newLI.setAttribute( 'id', 'nav_' + bucket.id );
      /*
      if( i == 0 ){
        newLI.addClassName( 'first' );
      }
      */
      if( i == (this.buckets.length - 1) ){
        newLI.addClassName( 'last' );
      }
      var newA = document.createElement( 'a' );
      newA.setAttribute( 'href', '#' );
      newA.innerHTML = bucket.name;
      newLI.appendChild( newA );
      if( bucket.subtitle && bucket.subtitle != '' ){
        var newSpan = document.createElement( 'span' );
        Element.extend( newSpan );
        newSpan.addClassName( 'navSubtitle' );
        newSpan.innerHTML = bucket.subtitle;
        newLI.appendChild( newSpan );
      }
      primaryUL.appendChild( newLI );
      Element.hide( newLI.id );
      new Effect.Appear( newLI.id, {delay: (i * 0.75)} );
    }
  }
	
}; // end Module
