/**
 * @author bob.crowley
 */
if (! CROWCODER)
{
    var CROWCODER = {};  
}

/**
 * @constructor 
 * @classDescription Creates a wizard object.
 */
CROWCODER.Wizard = function()
{
    this.wizard_title = "";
    this.step_count = 0;
    this.curr_step = 1;
    this.steps = [];  
    this.AddStep = CROWCODER.Wizard.Add_Step;
    this.MoveNext = CROWCODER.Wizard.Move_Next;
    this.MovePrev = CROWCODER.Wizard.Move_Prev;
    this.Render = CROWCODER.Wizard.Render;
    this.MoveTo = CROWCODER.Wizard.Move_To;
    this.steplist = document.createElement("OL");
    this.steplist.className = "wizlist";
    this.SetBtns = CROWCODER.Wizard.Set_Btns;
    this.SetNextLbl = CROWCODER.Wizard.Set_Next_Lbl;
    this.SetPrevLbl = CROWCODER.Wizard.Set_Prev_Lbl;
    
    this.nextVal = "Next";
    var btnNext = document.createElement("BUTTON");
    this.lblNext = document.createTextNode(this.nextVal);
    btnNext.appendChild(this.lblNext);
    btnNext.id = "btnnext";
    btnNext.onclick = this.MoveNext;
    btnNext.wzrd = this;
    this.nextBtn = btnNext;
    
    this.prevVal = "Previous";
    var btnPrev = document.createElement("BUTTON");
    this.lblPrev = document.createTextNode(this.prevVal);
    btnPrev.appendChild(this.lblPrev);
    btnPrev.id = "btnprev";
    btnPrev.onclick = this.MovePrev;
    btnPrev.wzrd = this;
    this.prevBtn = btnPrev;
    
    document.getElementById("wizbtns").appendChild(btnPrev);
    document.getElementById("wizbtns").appendChild(btnNext);
}//constructor

/**
 * @method Set_Next_Lbl
 * @param {String} p_label - The text to appear on the "Next"
 * button.
 */
CROWCODER.Wizard.Set_Next_Lbl = function(p_label)
{
    this.lblNext.data = p_label;    
}

/**
 * @method Set_Prev_Lbl
 * @param {String} p_label - The text to appear on the "Previous"
 * button.
 */
CROWCODER.Wizard.Set_Prev_Lbl = function(p_label)
{
    this.lblPrev.data = p_label;    
}

/**
 * @method WizardStep - Creates a wizard step object.
 * Intended to be added to the steps collection of your wizard.
 */
CROWCODER.Wizard.WizardStep = function()
{
    //step_name is the text that appears in the ordered list of steps
    this.step_name = "";
    
    //step_hint is the text that describes the step.
    this.step_hint = "";
}

/**
 * @method Add_Step - adds a wizard step object to the wizard's
 * collection of steps.
 * @param {WizardStep} p_step
 */
CROWCODER.Wizard.Add_Step = function(p_step)
{
    this.steps[this.step_count] = p_step;
    this.step_count = this.steps.length;
  
    //create the step list element for this step
    var step = document.createElement("LI");
    var steplink = document.createElement("a");
    steplink.href = "javascript:void(0)";  
    steplink.className = "offstep";
    steplink.id = "lnk" + this.step_count;
    var stepTxt = document.createTextNode(p_step.step_name);
    step.stepText = p_step.step_name;
    step.nbr = this.step_count;
    step.onclick = this.MoveTo;
    step.wiz = this;
    steplink.appendChild(stepTxt);
    step.appendChild(steplink);
    this.steplist.appendChild(step);
}

/**
 * @method - Move_Next: Advances the wizard one step forward.
 * Does not move if already on last step. Runs BeforeStepChange 
 * if implemented which provides an opportunity to cancel the
 * step change. 
 * After moving to next step, runs StepChanged if implemented.
 */
CROWCODER.Wizard.Move_Next = function()
{
    if(this.wzrd.curr_step < this.wzrd.step_count)
    { 
        if(this.wzrd.BeforeStepChange)
        {
             if ( !this.wzrd.BeforeStepChange())
             {
                 return;
             }
        }   
        
        for(var i = 1; i <= this.wzrd.step_count; i++)
        {
            document.getElementById("step" + i).className = "step_hidden";
            document.getElementById("lnk" + i).className = "offstep";
        }
        var nextstep = this.wzrd.curr_step + 1;
        document.getElementById("step" + nextstep).className = "step_visible";
        document.getElementById("lnk" + nextstep).className = "onstep";
        this.wzrd.curr_step += 1;
        document.getElementById("step_name").innerHTML =
            this.wzrd.steps[this.wzrd.curr_step - 1].step_hint;
            
        if(this.wzrd.StepChanged)
        {
         this.wzrd.StepChanged();
        }            
    } 
  
    this.wzrd.SetBtns();
}

/**
 * @method - Move_Prev: Advances the wizard one step backward.
 * Does not move if already on first step. Runs BeforeStepChange 
 * if implemented which provides an opportunity to cancel the
 * step change. 
 * After moving to the previous step, runs StepChanged if implemented.
 */
CROWCODER.Wizard.Move_Prev = function()
{
    if(this.wzrd.curr_step > 1)
    {
        if(this.wzrd.BeforeStepChange)
        {
             if ( !this.wzrd.BeforeStepChange())
             {
                 return;
             }
        }
        
        for(var i = 1; i <= this.wzrd.step_count; i++)
        {
            document.getElementById("step" + i).className = "step_hidden";
            document.getElementById("lnk" + i).className = "offstep";
        }
        var nextstep = this.wzrd.curr_step - 1;
        document.getElementById("step" + nextstep).className = "step_visible";
        document.getElementById("lnk" + nextstep).className = "onstep";
        this.wzrd.curr_step -= 1;
       
        document.getElementById("step_name").innerHTML =
            this.wzrd.steps[this.wzrd.curr_step - 1].step_hint;
            
        if(this.wzrd.StepChanged)
        {
         this.wzrd.StepChanged();
        }
    }
    this.wzrd.SetBtns();
}

/**
 * @method Move_To - Moves to the step selected in the ordered list
 * of steps. Provides alternate navigation to the Next and Previous 
 * buttons. Runs BeforeStepChange if implemented which provides an
 * opportunity to cancel the move. After the move, runs StepChanged
 * if implemented.
 */
CROWCODER.Wizard.Move_To = function()
{
    if(this.wiz.BeforeStepChange)
    {
       if ( !this.wiz.BeforeStepChange())
       {
           return;
       }
    }
    
    this.wiz.curr_step = this.nbr; 
  
    for(var i = 1; i <= this.wiz.step_count; i++)
    {
        document.getElementById("step" + i).className = "step_hidden";   
        document.getElementById("lnk" + i).className = "offstep"; 
    }
    var curstep = document.getElementById("step" + this.nbr);
    curstep.className = "step_visible";
     
    document.getElementById("lnk" + this.nbr).className = "onstep";
              
    document.getElementById("step_name").innerHTML =
            this.wiz.steps[this.wiz.curr_step - 1].step_hint;
                       
    if(this.wiz.StepChanged)
    {
         this.wiz.StepChanged();
    }
    this.wiz.SetBtns();
}

/**
 * @method Render - Shows the wizard to the web page.
 * @param {DOM Element} p_elem - the DOM element (should be <div>) 
 * where the ordered list of steps will be shown.
 */
CROWCODER.Wizard.Render = function(p_elem)
{
    var wizdiv = document.getElementById(p_elem);
    wizdiv.appendChild(this.steplist);
    document.getElementById("lnk1").className = "onstep";
    document.getElementById("btnprev").className = "step_hidden";
   
    document.getElementById("wiztitle").innerHTML = this.wizard_title;
    document.getElementById("step_name").innerHTML =
            this.steps[0].step_hint;
           
    document.getElementById("step1").className = "step_visible";
       
}

/**
 * @method Set_Btns - Shows or hides the navigation buttons as
 * appropriate for the current step.
 */
CROWCODER.Wizard.Set_Btns = function()
{
    var btnnext = document.getElementById("btnnext");
    var btnprev = document.getElementById("btnprev");
  
    switch (this.curr_step)
  {
    case 1:
    {
        btnprev.className = "btnhidden";
        btnnext.className = "btnvisible";
        break;
    }
    case this.step_count:
    {
        btnprev.className = "btnvisible";
        btnnext.className = "btnhidden";
        break;
    }
    default:
    {
        btnprev.className = "btnvisible";
        btnnext.className = "btnvisible";
        break;   
    }
  }
}
