/*

TODO:
1) display history array as string for output
2) optimize backtrack and store history

*/


(function($){
  
  var settings = {
	startPane: "pane1", //pane to start on, default first
	historyArr: new Array(), //array to house history (Ex: ["pane1", "pane3", "pane7"])
	timeTravel: false, //allow user to go to previous pane, enables previous buttons
	rewriteHistory: false, //allow user to choose another option on previous pane
	debug: false,
	choice: function() {},
	beforePaneChange: function(){},
	afterPaneChange: function(){},
	currentPane: null,
	showdebugtools: false,
	dynamicPanes: [],
	$this: null
  };

  var tracker = 0; //keep up with previous pane
  var valid = true;
  
  // private callback
  function callback(evt,name,params) {
	 if(typeof(params) == 'undefined') params=[];
	 var caller = (typeof(evt.target) == 'undefined') ? evt : evt.target;
	 $(caller).trigger(name+'.btlo',params);
	 if(eval('typeof(settings.'+name+')') != 'undefined')
	   eval('settings.'+name+'(caller,params);');
  } // callback
  
  var methods = {
  
    // init
	init : function(options) {
      
	  return this.each(function(){
        
		if(options)  $.extend(settings, options);
		
		var $this = $(this);
		settings.$this = $this;
		
		settings.currentPane = settings.startPane;
		
		$this.branchingTree('addToHistory',settings.currentPane);   
	   
		var divs = $this.children("div");
		divs.addClass('branchingTreePane');
		divs.addClass('hide');
		divs.filter("."+settings.currentPane).removeClass('hide');
        
		if(settings.debug == true) {
		  $this.after('<div id="btlodebugtool"></div>');
		  $debugtool = $('#btlodebugtool');
		  $(".choice",$this).each(function() {
		    targetPane = getTargetPaneFrom(this);
		    $debugtool.append('<a href="'+targetPane+'" class="choice">'+targetPane+'</a> | ');						  
		  });
		}
		
		if(typeof($debugtool) != 'undefined') {
		  
		  // bind seek operations
		  $debugtool.find(".choice").live('click', function(e) {
			
			var $choice = $(this);
			var targetPane = "";
            
			$(".choice",$debugtool).css('font-weight','normal');
			$(this).css('font-weight','bold');
			targetPane = getTargetPaneFrom(this);
			$this.branchingTree('gotoPane',targetPane);
			e.preventDefault();
			
		  }); // bind click
		  
		  // bold the current pane
		  $('body').bind('afterPaneChange',function(e) {
		    $('a',$debugtool).each(function() {
			  if($(this).html() == settings.currentPane) {
			    $(this).css('font-weight','bold');
				$(this).css('text-decoration','underline');
			  } else {
				$(this).css('font-weight','normal');  
				$(this).css('text-decoration','none');
			  }
			});
		  });
		  
		} // if debug tool
		
		$this.find(".choice").live('click', function(e) {
		  
		  var $choice = $(this);
		  var targetPane = "";

		  targetPane = getTargetPaneFrom(this);
		  
		  if(!$choice.hasClass('historyHighlight'))
			$this.branchingTree('addToHistory',targetPane);
			
		  $this.branchingTree('gotoPane',targetPane);

		  callback(e,'choice',[targetPane]);
		  
		  
		  tracker++;
				
		  e.preventDefault();
		  
		}); // bind click
		
		if(!settings.timeTravel)
			$this.find('.previous').css('display','none');
		
		$this.find('.previous').click(
		  function(e){
				tracker--;
				$this.branchingTree('gotoPane',options.historyArr[tracker]);
				
				if(settings.rewriteHistory)
					settings.historyArr.pop();
					
				e.preventDefault();
		}); // find previous
		
	  }); // this.each
	
	}, // init

	isValid : function(_valid) {
		valid = _valid;
	},

	getIndex : function() {
		return settings.currentPane;
	},

	// public gotoPane
	gotoPane : function(pane){ //go to next pane based on choice
	  return this.each(function() {
					
			$this = $(this);
			
			if(typeof(settings.dynamicPanes[pane]) != 'undefined') pane = settings.dynamicPanes[pane];
			
			callback($this,'beforePaneChange');
	  	
	  	if (valid) {

				$this.children("."+settings.currentPane).addClass("hide"); //hide current pane
				$this.children("."+pane).removeClass("hide"); //reveal destination pane
				settings.currentPane = pane; //update current pane
			
			
				callback($this,'afterPaneChange');
	  
				checkForEnd(settings.currentPane);
			}
		
	  }); // this.each
	}, // gotoPane
	
	
	// public addToHistory
	addToHistory : function(pane) {
	  return this.each(function() {
	    settings.historyArr.push(pane);
	  });
	}, // addToHistory 	

   
    // public addDynamicLink
	addDynamicLink : function(linkName,pane) {
	  settings.dynamicPanes[linkName] = pane;	
	}

  }; // methods
	
  
  // private checkForEnd
  function checkForEnd(pane) {
	$paneToCheck = settings.$this.find("."+pane);
	if($paneToCheck.hasClass('end')) 
	  callback($paneToCheck,'finish');
  } // checkForEnd
  
  // private getTargetPaneFrom
  function getTargetPaneFrom(thisref) {
	var targetPane = "";
	
    switch(thisref.tagName){
	  case "A":
		  targetPane = $(thisref).attr('href');
		  break;
	  case "INPUT":
		  targetPane =  $(thisref).attr('alt');
		  break;
		case "BUTTON":
		  targetPane =  $(thisref).attr('title');
		  break;
	  case "IMG":
		  targetPane =  $(thisref).attr('alt');
		  break;
	  default:
		  targetPane = currentPane;
	} //switch
	return targetPane;
  } // getTargetPaneFrom

  
  // plugin
  $.fn.branchingTree = function(method) {
    if (methods[method])
	  return methods[method].apply(this, Array.prototype.slice.call( arguments, 1));
	else if (typeof method === 'object' || ! method)
	  return methods.init.apply(this, arguments); // call init if no method is passed
	else
      alert('Method ' +  method + ' does not exist');  
  }; // $.fn.branchingTree
 
})(jQuery); // function($)
