var clk;
var sempty="                               ";
var smesg;
function MAjaxClock(vLimit,vForm,vForce,vExtra,vInterval,qcount,bDisabled)
{
    this.TimeLimit=vLimit;
    this.AlarmTime=Math.round(vLimit*0.9);
    this.ClockTime=this.TimeLimit-this.AlarmTime;
    this.RemainTime=vLimit;
    this.MyForm=vForm;
    this.ToForce=vForce;
    this.ExtraQueryString=vExtra;
    this.QueryString=vExtra;
    this.LastQueryString="";
    this.SaveInterval=vInterval;
    this.QCount=qcount;
    this.Disabled=bDisabled;
    smesg = document.getElementById("MTimer"); 
}

var cid1;

function updateClock()
{
    if (clk.RemainTime > clk.ClockTime && (clk.SaveInterval<=0 || (clk.TimeLimit-clk.RemainTime)%clk.SaveInterval > 0))
    {
        if (smesg != null)
        {
            smesg.innerHTML = "Remaining Time: " + checkTime(Math.floor(clk.RemainTime/3600)) + ":" 
                       + checkTime(Math.floor((clk.RemainTime%3600)/60)) + ":" 
                       + checkTime(clk.RemainTime%60);
        }
        window.status = "Remaining Time: " + checkTime(Math.floor(clk.RemainTime/3600)) + ":" 
                       + checkTime(Math.floor((clk.RemainTime%3600)/60)) + ":" 
                       + checkTime(clk.RemainTime%60);
    }
    if (clk.RemainTime == 0)
    {
         return;
    }
    clk.RemainTime = clk.RemainTime - 1;
    cid1=setTimeout("updateClock()", 1000);
}

function assureSubmit()
{
    var bret = true;
    if (clk.ToForce > 0)
    {
        // if this is an enforced, only alarm the user if has more than 10% time remaining
        if (clk.RemainTime > (0.1*clk.TimeLimit))
        {
            bret = confirm("You still have time to review your answers. Are you sure you want to submit?");
        }
    }
    else
    {
        var form = document.getElementById(clk.MyForm);
        // force user to answer all the questions since the timelimit is not forced
        if (!checkIfAllQuestionsAnswered(form))
        {
            alert("You need to answer all questions before submitting!");
            bret = false;
        }
    }
    return bret;
}

function alarmSubmit()
{
   // alarm
   if (clk.ToForce > 0)
   {
   	if (smesg != null)
       	{
       		smesg.innerHTML = sempty.substring(clk.RemainTime%30)+clk.RemainTime+" seconds left before submitting!";
        }
        window.status = sempty.substring(clk.RemainTime%30)+clk.RemainTime+" seconds left before submitting!";
    }
    else
    {
       	if (smesg != null)
       	{
       		smesg.innerHTML = clk.RemainTime+" seconds left!";
       	}
       	else
       	{
       		window.status = clk.RemainTime+" seconds left!";
       	}
    }
    if (clk.RemainTime <= 0)
    {
         return;
    }
    setTimeout("alarmSubmit()", 1000);
}

function forceSubmit()
{
    document.getElementById(clk.MyForm).submit();
}

function getQueryString()
{
    var form = document.getElementById(clk.MyForm);
    var query = buildQueryString(form)
    if (clk.ExtraQueryString != null)
    {
        query = query+"&"+clk.ExtraQueryString;
    }
    return query;
}

function checkTime(i)
{
    if (i<10) 
    {
        i="0" + i;
    }
    return i;
}

function toQueryComponent(input) 
{
    if (!input.name || input.disabled)
    {
        return "";
    }
    var n = urlencode(input.name);

    switch (input.type) 
    {
        case "text":
        case "password":
        case "submit":
        case "hidden":
            return n + "=" + urlencode(input.value);
        case "textarea":
            var v = input.value.replace(/(\r\n)|\r|\n/g, "\r\n");
            return n + "=" + urlencode(v);
        case "checkbox":
        case "radio":
            if (!input.checked)
                return "";
            return n + "=" + urlencode(input.value);
        case "select-one":
        case "select-multiple":
            var nvp = [];
            var opt, i = 0;
            while ((opt = input.options[i++]) != null) 
            {
                if (opt.selected) 
                {
                    var v = getRealValue(opt);
                    if (v === null) v = opt.text;
                    // older versions of IE do not support Array.push 
                    nvp[nvp.length] = n + "=" + urlencode(v);
                }
            }
            return nvp.join("&");
        default:
            // input types reset, button, image, and file not implemented 
            return "";
    }
}

function urlencode(str) 
{
    var v;
    try { 
        v = encodeURIComponent(str); 
    } catch (e) 
    { 
        v = escape(str); 
    }
    return v.replace(/%20/g,"+");
}

function isEmpty(input) 
{
    if (!input.name || input.disabled)
    {
        return false;
    }
    switch (input.type) 
    {
        case "text":
        case "password":
        case "submit":
        case "hidden":
        case "textarea":
             if (input.value == "") return true;
             else return false;
        case "checkbox":
        case "radio":
            if (input.checked)
                return false;
            return true;
        case "select-one":
        case "select-multiple":
            var nvp = [];
            var opt, i = 0;
            while ((opt = input.options[i++]) != null) 
            {
                if (opt.selected) 
                {
                    return false;
                }
            }
            return true;
        default:
            // input types reset, button, image, and file not implemented 
            return true;
    }
}

function checkIfAllQuestionsAnswered(form) 
{
    var element, i = 0;
    var icnt=0;
    while ((element = form.elements[i++]) != null) 
    {
        if (element.name != "MKEY" && element.name.charAt(0)=="Q")
        {
            if (!isEmpty(element))
            {
                icnt ++;
            }
        }
    }
    if (clk.QCount>icnt)
    {
        return false;
    }
    return true;
}

function buildQueryString(form) 
{
    var str = "";
    var element, i = 0;
    while ((element = form.elements[i++]) != null) 
    {
        if (element.name != "MKEY")
        {
            var qc = toQueryComponent(element);
            if (qc != "") str += "&" + qc;
        }
    }
    return str.substring(1);
}

function saveContent()
{  
  var sqstr = getQueryString(clk);
  if (sqstr != clk.LastQueryString)
  {
      clk.LastQueryString = sqstr;
      var xmlHttp;
      try
      {  
          // Firefox, Opera 8.0+, Safari    
          xmlHttp=new XMLHttpRequest();    
          if (xmlHttp.overrideMimeType) 
          {
             xmlHttp.overrideMimeType('text/html');
          }
      }
      catch (e)
      {    // Internet Explorer    
          try
          {      
              xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");      
          }
          catch (e)
          {      
              try
              {        
                  xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");        
              }
              catch (e)
              {        
                  alert("Your browser does not support AJAX and you may need to consider to update your browser!");        
                  return;        
              }      
           }    
       }
       xmlHttp.onreadystatechange=function()
       {
            if(xmlHttp.readyState==4)
            {
                if (smesg != null)
                {
                    smesg.innerHTML = xmlHttp.responseText;
                }
                else
                {
                    window.status = xmlHttp.responseText;
                }
            }
        }

       // build the query string dynamically
       xmlHttp.open("POST",document.getElementById(clk.MyForm).action,true);
       xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
       xmlHttp.send('MAJAX=1&'+sqstr);  
    }
}

function saveThread()
{ 
    saveContent(); 
    setTimeout("saveThread()",clk.SaveInterval*1000);
}

function initClock(c) 
{
   clk = c;
   if (!(clk.Disabled)) {
   	if (clk.TimeLimit > 0 )
   	{
       		cid1=setTimeout("updateClock()", 1000);
   	}
   	if(clk.ToForce > 0)
   	{
        	setTimeout("forceSubmit()", clk.TimeLimit*1000);
   	}
   	setTimeout("alarmSubmit()", clk.AlarmTime*1000);
   }
   if (clk.SaveInterval > 0)
   {
       clk.LastQueryString=getQueryString();
       setTimeout("saveThread()", clk.SaveInterval*1000);
   }
}


