/**********************************************************
 *   SCRIPT NAME
 *      Question.js
 *
 *   MODIFICATION HISTORY
 *   Ver  Date     Author     Desc
 *   ---  ----     ------     ----
 *   1.0  08/2006  Ron Lewis  Creation
 *   1.1  02/2007  Ron Lewis  Added capability to handle more than 1 digit in map questions
 *   1.2  02/2007  Ron Lewis  Reference section doesn't print if empty
 *                            Fixed bug related to showing the proper selected answer when incorrect
 **********************************************************/

Question = function(intype)
{

   //   multi    - multiple choice
   //   map      - map from table
   //   mapimage - map from image
   if (intype == 'multi'
       || intype == 'map')
   {
      this.type = intype;
   }
   else
      alert('Problem with question type = ' + intype);

   //   displayable elements
   this.question = [];
   this.choices = [];
   this.answers = [];
   this.reference = [];
   this.Qimages = [];

   //   scoring variables
   this.questioncount = 0;
   this.correctcount = 0;
   this.incorrectcount = 0;
   this.unansweredcount = 0;

   //   random sorting variables
   this.arrRandom = [];

   //   formatting options
   this.formatnumbercelltext = ' valign="middle" bgcolor="#0000AA" ';
   this.formatnumberfonttext = ' face="Arial Narrow, Arial, Geneva" color="#FFFFFF" size="+3" ';
   this.formatquestioncelltext = ' align="top" bgcolor="#EEEEEE" ';
   this.formatquestionfonttext = ' face="Arial Narrow, Arial, Geneva" color="#000000" size="+0" ';
   this.Qnumbgcolor = 'blue';
   this.Qnumcolor = 'white';
   this.Qnumsize = '6';
   this.Qbgcolor = '#EEEEEE';
   this.Qcolor = 'black';

//
//   Simple set/add functions
// **************************
   this.addquestion = function(questiontext)
   {
      this.question.push(questiontext);
   }

   this.addimage = function(imageurl)
   {
      this.Qimages.push(imageurl);
   }

   this.addchoice = function(choicetext, answertext)
   {
      this.choices.push(choicetext);
      this.answers.push(strtrim(answertext));
   }

   this.addreference = function(referencetext)
   {
      this.reference.push(referencetext);
   }

//
//   Show question
// ***************
   this.paintquestion = function(intQnum)
   {
      var retval = '';

      retval = this.openQtable(intQnum);

   //   print question
      for (i = 0; i < this.question.length; i++)
      {
         retval += this.question[i] + '<br>';
      }
      if (this.question.length > 0)
         retval += '<br>';

   //   print images
      for (i = 0; i < this.Qimages.length; i++)
      {
         retval += '<img src="' + this.Qimages[i] + '"><br>';
      }
      if (this.Qimages.length > 0)
         retval += '<br>';

   //   print choices + grade answers
      this.scrambleAnswers(this.choices.length);
   //   multiple choice
      if (this.type == 'multi')
      {
         for (i = 0; i < this.choices.length; i++)
         {
            if (this.answers[this.arrRandom[i]] == 'right')
               curanswer = 'right';
            else
//               curanswer = '' + i;
               curanswer = '' + this.arrRandom[i];

            retval += '<input type="radio" name="Q' + intQnum + '" value="' + curanswer + '">' + this.choices[this.arrRandom[i]] + '<br>';
         }
      }
   //   map
      else if (this.type == 'map')
      {
         retval += '<table>';
         initanswer = '';
         for (i = 0; i < this.choices.length; i++)
         {
            retval += '<tr>';
            retval += '<td>' + this.choices[i] + '</td>';
            retval += '<td><input type="input" name="' + i + 'Q' + intQnum + '" size="2" maxlength="2" onkeyup="AnswerAppend' + intQnum + '()"></td>';
            retval += '</tr>';

            initanswer += '_';
         }
         retval += '</table>';

         //   Handle answers
         retval += '<input type="hidden" name="Q' + intQnum + '" value="' + initanswer + '">';
         retval += '<script>';
         retval += 'function AnswerAppend' + intQnum + '()';
         retval += '{';
         retval += '   document.all.item("Q' + intQnum + '").value = "";'
         retval += '   for (i = 0; i < ' + this.choices.length + '; i++)';
         retval += '   {';
         retval += '      if (document.all.item(i + "Q' + intQnum + '").value == "")';
         retval += '         document.all.item("Q' + intQnum + '").value += "0";';
         retval += '      else';
         retval += '         document.all.item("Q' + intQnum + '").value += strtrim(document.all.item(i + "Q' + intQnum + '").value).length + strtrim(document.all.item(i + "Q' + intQnum + '").value);';
         retval += '   }';
         retval += '}';
         retval += '</script>';
      }

      retval += this.closeQtable();

      document.write(retval);
   }

//
//   Show answered question
// ************************
   this.paintanswered = function(intQnum, answer)
   {
      var retval = '';
      var wronganswer = false;
      var found = false;

      retval = this.openQtable(intQnum);

      //   multiple choice
      if (this.type == 'multi')
      {
         //   Show answer status
         if (answer == '')
         {
            retval += '<b>Unanswered</b><br><br>';
            wronganswer = true;
         }
         else if (answer == 'right')
            retval += '<b>Correct</b><br><br>';
         else
         {
            retval += '<b>Incorrect</b><br><br>';
            wronganswer = true;
         }
//alert('initial: |' + answer + '|' + wronganswer + '|');
      }

      //   print question
      for (i = 0; i < this.question.length; i++)
      {
         retval += this.question[i] + '<br>';
      }
      if (this.question.length > 0)
         retval += '<br>';

      //   print images
      for (i = 0; i < this.Qimages.length; i++)
      {
         retval += '<img src="' + this.Qimages[i] + '"><br>';
      }
      if (this.Qimages.length > 0)
         retval += '<br>';

      //   print answers
      //   multiple choice
      if (this.type == 'multi')
      {
         for (i = 0; i < this.choices.length; i++)
            if (this.answers[i] == 'right')
               retval += '<b>Answer:</b> ' + this.choices[i] + '<br>';

         if (wronganswer)
         {
            found = false
            for (i = 0; i < this.choices.length && !found; i++)
            {
               if (this.answers[i] == 'right')
                  curanswer = 'right';
               else
                  curanswer = '' + i;

               if (curanswer == answer)
               {
                  found = true;
                  retval += '<b>Your Answer:</b> ' + this.choices[i] + '<br>';
               }
//alert('loop: |' + answer + '|' + curanswer + '|');
            }

            if (this.reference.length > 0)
            {
               retval += '<br>';
               retval += '<table border="1">';
               retval += '<tr><td>';
               for (i = 0; i < this.reference.length; i++)
                  retval += this.reference[i] + '<br>';
               retval += '</td></tr>';
               retval += '</table>';
            }
         }
      }

      //   map
      else if (this.type == 'map')
      {
         retval += '<table border=1>';
         retval += '<tr>';
         retval += '   <td></td><td></td>';
         retval += '   <td><b>Your Answer</b></td>';
         retval += '   <td><b>Correct Answer</b></td>';
         retval += '</tr>';

         j = 0;
         for (i = 0; i < this.choices.length; i++)
         {
            retval += '<tr>';
            curanswerlen = answer.substr(j, 1);
            if (curanswerlen == '0')
               curanswer = 'No Answer';
            else
               curanswer = answer.substr(j + 1, parseInt(curanswerlen));
//alert(answer + '|' + j + '|' + curanswerlen + '|' + curanswer);
            if (curanswer.toLowerCase() == this.answers[i].toLowerCase())
               retval += '   <td><b>Correct</b></td>';
            else
               retval += '   <td><b>Incorrect</b></td>';

            retval += '   <td>' + this.choices[i] + '</td>';
            retval += '   <td>' + curanswer + '</td>';
            retval += '   <td>' + this.answers[i] + '</td>';
            retval += '</tr>';

            j += parseInt(curanswerlen) + 1;
         }
         retval += '</table>';
      }

      retval += this.closeQtable();

      document.write(retval);
   }

//
//   Score this question
// *********************
   this.score = function(answer)
   {
      answer = answer.toLowerCase();

   //   multiple choice
      if (this.type == 'multi')
      {
         this.questioncount++;

         if (answer == '')
            this.unansweredcount++;
         else if (answer == 'right')
            this.correctcount++;
         else
            this.incorrectcount++;
      }
   //   map
      else if (this.type == 'map')
      {
         j = 0;
         for (i = 0; i < this.choices.length; i++)
         {
            this.questioncount++;

            curanswerlen = answer.substr(j, 1);
            if (curanswerlen == '0')
               curanswer = ''
            else
               curanswer = answer.substr(j + 1, parseInt(curanswerlen));

            if (curanswer.toLowerCase() == this.answers[i].toLowerCase())
               this.correctcount++;
            else if (curanswerlen == '0')
               this.unansweredcount++;
            else
               this.incorrectcount++;

            j += parseInt(curanswerlen) + 1;
         }
      }
   }

//
//   Utility functions
// *******************/
   this.openQtable = function(intQnum)
   {
      var retval = '';

      retval  = '<table border="0" cellpadding="5">';
      retval += '<tr>';
   //   print question number
      retval += '   <td ' + this.formatnumbercelltext + '><font ' + this.formatnumberfonttext + '><b>' + intQnum + '</b></font></td>';

   //   Open cell for question information
      retval += '   <td ' + this.formatquestioncelltext + '><font ' + this.formatquestionfonttext + '>';

      return retval;
   }

   this.closeQtable = function(intQnum)
   {
      var retval = '';

      retval  = '   </font>';
      retval += '   </td>';
      retval += '</tr>';
      retval += '</table>';

      return retval;
   }

   this.scrambleAnswers = function(insize)
   {
      this.arrRandom = new Array(insize);

      for (i = 0; i < insize; i++)
      {
         fnd = true;
         while (fnd)
         {
            curindex = parseInt(Math.random() * insize);
            fnd = false;

            for (j = 0; j < i && !fnd; j++)
               if (this.arrRandom[j] == curindex)
                  fnd = true;
         }

         this.arrRandom[i] = curindex;
      }
   }

}

function strtrim(inchar)
{
   var retval = '';
   var whitespace = ' ';
   var i;
   var ibeg, iend;
//alert('|' + inchar + '|');
   //   Find beginning
   ibeg = -1;
   for (i = 0; i < inchar.length && ibeg == -1; i++)
      if (whitespace.indexOf(inchar.substr(i, 1)) == -1)
         ibeg = i;
//alert('|' + ibeg + '|');
   if (ibeg == -1)
      ibeg = 0;

   //   Find end
   iend = -1;
   for (i = inchar.length - 1; i >= 0 && iend == -1; i--)
      if (whitespace.indexOf(inchar.substr(i, 1)) == -1)
         iend = i;
//alert('|' + iend + '|');
   if (iend == -1)
      retval = '';
   else
      retval = inchar.substring(ibeg, iend + 1);
//alert('|' + retval + '|');
   return retval;
}
