/*
  check-tc-main.js
  (c) 2008-2009-2011 Misha Yurasv
*/

var dbg = function() { return '&XDEBUG_SESSION_START=netbeans-xdebug&debug_no_cache=' + Math.round(Math.random()*1000000) };

// [Require]

dojo.require('dojo.io.iframe');

// [Code]

// Constants

var consts = {

  // Misc error
  "ERROR_OK" : 0,
  "ERROR_MISC" : -1,

  // Scan result
  "SCAN_OK" : 0,
  "SCAN_INFECTED" : 1,

  // File check errors
  "CHECK_FILE_ERR_MISC" : -1,
  "CHECK_FILE_ERR_UPLOAD" : 1,
  "CHECK_FILE_ERR_MAXSIZE" : 2,

  // Feedback sending errors
  "FEEDBACK_ERR_VKEY" : 1,
  "FEEDBACK_ERR_MAIL" : 2,

  // URL download progress errors
  "UD_ERR_NO_PROGRESS" : 1
};

// Vars

var curPage;
var curScreen;
var curTheme;
var cert_timeout;
var urlProgressBar;
var fileProgressBar;

/**
  * Apply page theme
  *
  * @param string theme
  *
  */
function applyTheme(theme)
{
  if (!dojo.hasClass(document.body))
  {
    if (typeof(curTheme) != 'undefined')
    {
      dojo.removeClass(document.body, curTheme);
    }

    dojo.addClass(document.body, theme);
    curTheme = theme;

    // iframes

    var ads = document.getElementsByTagName('iframe');

    for (i = 0, j = 0; i < ads.length; i++)
    {
      if (ads[i].className == 'themed')
      {
        ads[i].src = ads[i].getAttribute('source').replace('%theme%', theme);
      }
    }
  }
}

var showPage_npages = 0;
/**
  * Show one of the main pages
  *
  * @param int npage
  */
function showPage(npage)
{
  var spage = dojo.byId('page_' + npage);

  // reset page
  if (spage == getCurrentPage())
  {
    resetPage(dojo.byId('page_' + npage));
  }

  showPage_npages = showPage_npages == 0 ? dojo.query('.page').length : showPage_npages;

  for (i = 1; i <= showPage_npages; i++)
  {
    dojo.addClass(dojo.byId('page_' + i), 'nodisplay');
    dojo.removeClass(dojo.byId('tabLink_' + i), 'active_tab');
  }

  dojo.removeClass(spage, 'nodisplay');
  dojo.addClass(dojo.byId('tabLink_' + npage), 'active_tab');

  // init page

  switch (npage)
  {
    case 4:
    {
      showStats();
      break;
    }
  }
}

/**
  * Reset page
  *
  */
function resetPage(opage)
{
  if (typeof opage == 'undefined')
  {
    opage = getCurrentPage();
  }
  
  switch (opage.id)
  {
    case 'page_1':
    {
      if (getCurrentScreen().id != 'page_1_screen_2')
      {
        showFile(true);
        showScreen('page_1_screen_1');
        applyTheme('b');
      }

      break;
    }
  
    case 'page_2':
    {
      showScreen('page_2_screen_1');
      applyTheme('b');
      break;
    }
    
    case 'page_3':
    {
      showScreen('page_3_screen_1');
      applyTheme('b');

      break;
    }

    case 'page_4':
    {
      showStats();

      break;
    }
  }
}

/**
  * Get current page node
  *
  */
function getCurrentPage()
{
  var pages = dojo.query('.page');
  var cpage;
  pages.forEach(function(x) { if (!dojo.hasClass(x, 'nodisplay')) { cpage = x; } });
  return cpage;
}

/**
  * Get current screen node
  *
  */
function getCurrentScreen()
{
  var cpage = getCurrentPage();
  var screens = dojo.query('#' + cpage.id + ' .screen');
  var cscreen;
  screens.forEach(function(x) { if (!dojo.hasClass(x, 'nodisplay')) { cscreen = x; } });
  return cscreen;
}

var updateUploadProgress_timeout;
var updateUploadProgress_prev_percent = -1;
/**
  * Update file upload progress
  *
  * @param uid string
  */
function updateUploadProgress(uid)
{
  var dfdProgress = dojo.xhrGet({
    url: '/api.php',
    content: {api: 'upload_progress', uid: uid},
    preventCache: true,
    handleAs: 'json'
  });

  dfdProgress.addCallback(function(data) {
    if (data.error == consts.ERROR_OK)
    {
      var percent = typeof(data.percent) == 'undefined' ? 0 : data.percent;

      if (updateUploadProgress_prev_percent > 0 && typeof(data.percent) == 'undefined') // file uploaded
      {
        showUploadProgress(101);
      }
      else if (percent >= updateUploadProgress_prev_percent)
      {
        updateUploadProgress_prev_percent = percent;
        showUploadProgress(percent);
        updateUploadProgress_timeout = setTimeout("updateUploadProgress('" + uid + "')", 1000);
      }
    }
  });
}

/**
  * Display file upload progress
  *
  * @param percent integer
  */
function showUploadProgress(percent)
{
  if (percent > 100)
  {
    dojo.byId('p1_s1_uploadStatus').innerHTML = 'Scanning...';
    fileProgressBar.setPercent(100);
  }
  else
  {
    fileProgressBar.setPercent(percent);
  }
}

/**
  * Reset file upload progress indicator
  *
  */
function resetUploadProgress()
{
  showUploadProgress_cnt = 0;
  showUploadProgress(0);
  updateUploadProgress_prev_percent = -1;
  dojo.byId('p1_s1_uploadStatus').innerHTML = 'Uploading...';
}

/**
  * Return X-bit unique id hex string
  *
  */
function hexUID(bits)
{
  var uid = '';
  var c = '01234567890abcdef';
  var s = Math.round(bits / 4);

  for (var i = 0; i < s; i++)
  {
    uid += c.charAt(Math.round(Math.random() * 16));
  }

  return uid;
}

/**
  * Upload and scan file
  *
  */
function scanFile()
{
  // check file selection

  var fI = dojo.byId('fileInput');

  if (fI.value == '')
  {
    alert('Please, select file first!');
    return;
  }

  // generate uid
  var upload_uid = hexUID(64);

  // set upload file id
  dojo.byId('UPLOAD_IDENTIFIER').value = upload_uid;

  // upload file
  var dfdCheck = dojo.io.iframe.send({
    url: '/api.php?api=scan_file',
    method: 'post',
    handleAs: 'json',
    form: dojo.byId('fileForm')
  });

  // start upload progress update
  updateUploadProgress(upload_uid);

  // show 'wait...' page
  var dfdShow2 = showScreen('page_1_screen_2');

  // request succeeded
  dfdCheck.addCallback(function(data){

    // stop upload progress update
    clearTimeout(updateUploadProgress_timeout);
    resetUploadProgress();

    switch (data.error)
    {
      case consts.ERROR_OK:
      {
        // display result
        dojo.byId('p1_s3_fileName').innerHTML = decodeURI(data.name);
        dojo.byId('p1_s3_fileStatus').innerHTML = data.result == consts.SCAN_OK ? 'Clean' : ('Infected with ' + data.infection);
        dojo.byId('p1_s3_fileMD5').innerHTML = data.md5;
        dojo.byId('p1_s3_fileSHA1').innerHTML = data.sha1;

        // certificate

        var dfdCert = showCert(data.md5, 'p1_s3_fileCert', 'p1_s3_certHTMLText');

        // show screen 3
        dfdShow2.addCallback(function() {

          // show screen 3
          var dfdShow3 = showScreen('page_1_screen_3');

          // apply theme
          dfdShow3.addCallback(function() {
            applyTheme(data.result == consts.SCAN_OK ? 'g' : 'r');
            dfdCert.addCallback( function(_cert_script) { cert_timeout = setTimeout(function () { eval(_cert_script); }, 100);  } );
          });

        });

        break;
      }

      case consts.CHECK_FILE_ERR_UPLOAD:
      case consts.CHECK_FILE_ERR_MISC:
      case consts.CHECK_FILE_ERR_MAXSIZE:
      {
       alert(data.message);
       dfdShow2.addCallback(function() { showScreen('page_1_screen_1') });
       break;
      }

      default:
      {
        alert('Unknown error');
      }
    }
  });

  // request failed
  //dfdCheck.addErrback(function(data){
  //  alert('Failed to upload file');
  //  showScreen('page_1_screen_1');
  //});
}

/**
  * Hides one screen and shows another one
  *
  * @param string|int show_id
  * @return dojo.Deferred
  *
  */
function showScreen(show_id, fast)
{
  var d = new dojo.Deferred();
  var h = getCurrentScreen();
  var s = typeof show_id == 'string' ? dojo.byId(show_id) : dojo.byId(getCurrentPage().id +  '_screen_' + show_id.toString());

  if (h != s)
  {
    try
    {
      if (fast)
      {
        dojo.addClass(h, 'nodisplay');
        dojo.addClass(h, 'transparent');
        dojo.removeClass(s, 'nodisplay');
        dojo.removeClass(s, 'transparent');
        d.callback(show_id);
      }
      else
      {
        dojo.fadeOut({node: h, duration: 250, onEnd: function () {
          dojo.addClass(h, 'nodisplay');
          dojo.addClass(h, 'transparent');
          dojo.removeClass(s, 'nodisplay');
          dojo.fadeIn({node: s, duration: 500, onEnd: function () {
            dojo.removeClass(s, 'transparent');
            d.callback(show_id);
          }}).play();
        }}).play();
      }
    }
    catch (e)
    {
      d.errback(e);
    }
  }

  return d;
}

/**
  * Executed on page load
  *
  */
function init()
{
  // read initialization data

  var initData = dojo.fromJson(dojo.byId('initData').innerHTML);

  // per-browser fixes

  if (dojo.isOpera)
  {
    if (typeof(dojo.byId('topAd')) != 'undefined')
    {
      dojo.byId('topAd').style.borderBottomStyle = 'none';
    }
  }

  // button style
  if (!dojo.isIE)
  {
    var bb = dojo.query('div.button');

    for (i = 0; i < bb.length; i++)
    {
      bb[i].style.height = bb[i].offsetHeight - 7 * 2;
    }
  }

  if (initData.mode == '' || initData.mode == 'cert')
  {
    // browse for file field

    var i = dojo.byId('fileInput');
    var b = dojo.byId('browseField1');
    var h = i.offsetHeight - b.offsetHeight;
    //
    if (h > 0)
    {
      b.style.top = h / 2;
    }
    else if (h < 0)
    {
      i.style.top = -1 * h / 2;
    }

    // reset file selection
    dojo.byId('browseField1_text').value = i.value = '';
  }

  if (initData.mode == '')
  {
    applyTheme('b');
    urlProgressBar = new myProgressBar(dojo.byId('url_progress_bar'));
    fileProgressBar = new myProgressBar(dojo.byId('file_progress_bar'));
  }
  else if (initData.mode == 'cert')
  {
    showPage(3);
    showScreen('page_3_screen_2', true);
    var dfdCert = showCert(initData.md5, 'p3_s2_fileCert', 'p3_s2_certHTMLText', initData.name);
    applyTheme(initData.result == consts.SCAN_OK ? 'g' : 'r');
    dfdCert.addCallback( function(_cert_script) { cert_timeout = setTimeout(function () { eval(_cert_script); }, 100);  } );
    urlProgressBar = new myProgressBar(dojo.byId('url_progress_bar'));
    fileProgressBar = new myProgressBar(dojo.byId('file_progress_bar'));    
  }
  else if (initData.mode == 'feedback')
  {
    autoScreensHeight();
    applyTheme('b');
  }
  else
  {
    applyTheme('b');
  }
}


/**
  * Show selected filename
  *
  */
function showFile(purge)
{
  var i = dojo.byId('fileInput');
  var t = dojo.byId('browseField1_text');

  if (purge == true)
  {
    t.value = '';
    i.value = '';
  }
  else
  {
    t.style.width = t.offsetWidth;
    t.value = i.value;
  }
}

/**
  * Show certificate HTML code
  *
  */
function showCertHTML(prefix)
{
  var c = dojo.byId(prefix + "_fileCert");
  var t = dojo.byId(prefix + "_certHTML");
  var l = dojo.byId(prefix + "_codeLink");

  if (dojo.hasClass(c, "nodisplay"))
  {
    dojo.removeClass(c, "nodisplay");
    dojo.addClass(t, "nodisplay");
    l.innerHTML = "Show HTML code";
  }
  else
  {
    dojo.addClass(c, "nodisplay");
    dojo.removeClass(t, "nodisplay");
    l.innerHTML = "Show image";
  }
}

/**
  * Search scan result by MD5 hash
  *
  */
function searchHash(hash_text)
{
  var h = dojo.byId('hashSearch_text');

  if (h.value == '')
  {
    alert('Please, enter MD5 or SHA-1 hash first!');
    return;
  }

  // search for hash

  var dfdSearch = dojo.xhrGet({
    url : '/api.php?api=search_hash&' + dojo.formToQuery(dojo.byId('hashSearch_form')),
    handleAs : 'json'
  });

  dfdSearch.addCallback(function(data) {

    if (data.error != consts.SCAN_OK)
    {
      // error
      alert(data.message);
    }
    else if (data.found == false)
    {
      // hash not found
      alert('File with hash "' + h.value + '" not found');
    }
    else if (data.found == true)
    {
      // display result
      dojo.byId('p3_s2_fileName').innerHTML = decodeURI(data.name);
      dojo.byId('p3_s2_fileStatus').innerHTML = data.result == consts.SCAN_OK ? 'Clean' : ('Infected with ' + data.infection);
      dojo.byId('p3_s2_fileMD5').innerHTML = data.md5;
      dojo.byId('p3_s2_fileSHA1').innerHTML = data.sha1;

      var dfdCert = showCert(data.md5, 'p3_s2_fileCert', 'p3_s2_certHTMLText');
      var dfdShow2 = showScreen('page_3_screen_2');

      dfdShow2.addCallback(function(_cert_script) {
        applyTheme(data.result == consts.SCAN_OK ? 'g' : 'r');
        dfdCert.addCallback(function(_cert_script) {cert_timeout = setTimeout(function () { eval(_cert_script); }, 100); } );
      });
    }
  });

}

/**
  * Show certificate image
  *
  * @return dojo.Deferred
  */
function showCert(md5, image_obj_id, code_obj_id, name)
{
  var dfd = new dojo.Deferred();

  var dfdCert = dojo.xhrGet({
    'url'       : '/api.php',
    'content'   : {api: 'make_cert_code', md5 : md5, name : name},
    'handleAs'  : 'json'
  });
  //
  cert_script = '';
  cert_timeout = null;
  //
  dfdCert.addCallback(function(data) {
    if (data.error == consts.ERROR_OK)
    {
      var code = data.code;
    }
    else
    {
      var code = data.message;
    }
    //
    dojo.byId(image_obj_id).innerHTML = code;
    dojo.byId(code_obj_id).value = code;

    cert_script = code.replace(/^.+<script.+?>/, '').replace(/<\/script>/, '');
    cert_script += "\nclearTimeout(cert_timeout);";

    dfd.callback(cert_script);

  });

  return dfd;
}

/**
  * Show statisstics
  *
  */
function showStats()
{
  var dfdStats = dojo.xhrGet({
    url : '/api.php?api=get_stats',
    handleAs : 'json'
  });

  dfdStats.addCallback(function(data) {

    dojo.byId('p4_s1_totalFiles').innerHTML = data.total_files;

    dojo.byId('p4_s1_cleanFiles').innerHTML = data.clean_files;
    if (data.clean_files > 0) { dojo.byId('p4_s1_cleanFiles').innerHTML +=  ' (' + Math.round(data.clean_files / data.total_files  * 100) + '%)' };

    dojo.byId('p4_s1_infectedFiles').innerHTML = data.infected_files;
    if (data.infected_files > 0) { dojo.byId('p4_s1_infectedFiles').innerHTML +=  ' (' + Math.round(data.infected_files / data.total_files  * 100) + '%)' };
  });
}

/**
  * Send feedback
  *
  */
function sendFeedback()
{
  // input checks

  var fillFields = '';

  if (dojo.byId('frmFeedback_name').value == '')
  {
    fillFields += "\n* Your name";
  }

  if (dojo.byId('frmFeedback_feedback').value == '')
  {
    fillFields += "\n* Feedback";
  }

  if (dojo.byId('frmFeedback_vkey').value == '')
  {
    fillFields += "\n* Text on the picture";
  }

  if (fillFields != '')
  {
    alert('Please, fill the following fields:' + fillFields);
    return;
  }

  var dfdSend = dojo.xhrPost({
    url       : '/api.php?api=send_feedback',
    form      : 'frmFeedback',
    handleAs  : 'json'
  });

  dfdSend.addCallback(function(data) {

    var updateVKey = function()
    {
      var vkey_uid = Math.round(Math.random() * 2147483647);
      dojo.byId('vkey_image').src = '/view.php?view=vkey&uid=' + vkey_uid;
      dojo.byId('frmFeedback_vkey_uid').value = vkey_uid;
    };

    if (data.error == consts.FEEDBACK_ERR_VKEY)
    {
      alert('Wrong letters on the picture entered');
      updateVKey();
    }
    else if (data.error == consts.ERROR_OK)
    {
      dojo.byId('message').innerHTML = "Feedback sent.<br>It will be reviewed and answered shortly.<br>Thank you!";
      showScreen('page_1_screen_2');
    }
    else if (data.error == consts.FEEDBACK_ERR_MAIL)
    {
      alert("Error sending message:\n" + data.message);
      updateVKey();
    }
    else
    {
      alert(data.message);
      updateVKey();
    }

  });
}

/**
  * Equalize screens height
  *
  */
function autoScreensHeight()
{
  var maxHeight = 0;
  var screens = dojo.query('.screen');

  // find max height

  for (var i = 0; i < screens.length; i++)
  {
    if (screens[i].offsetHeight > maxHeight)
    {
      maxHeight = screens[i].offsetHeight;
    }
  }

  // apply

  dojo.byId('content_table').style.height = maxHeight + 'px';
}

/**
  * URL scanner
  *
  */
var urlScanner = function(url, uid)
{
  this.url = url;
  this.uid = uid;
  
  if (url == '')
  {
    throw "Please, input URL to scan";
  }
  
  /**
    * Get URL progress and fire callback each time it arrives
    *
    * @return dojo.Deferred;
    */
  this.getURLProgress = function()
  {
    var dfdProgress;
  
    // Timeout
    var t;
  
    // Canceller
    var c = function(dfd) {
      dfdProgress.cancel();
      clearTimeout(t);
    };
  
    // Deferred
    var d = new dojo.Deferred(c);
    
    // UID
    var uid = this.uid;
  
    // Progress getter
    var p = function() {
  
      dfdProgress = dojo.xhrGet({
        url: '/api.php',
        content: {api: 'url_download', method: 'url_progress', uid: uid},
        handleAs: 'json',
        preventCache: true
      });
  
      dfdProgress.addCallback(function(data) {
        d.showProgress(data);
        t = setTimeout(p, 777);
      });
  
      dfdProgress.addErrback(function() { d.errback() });
  
    };
  
    p();
  
    return d;
  };

  /**
    * Shows URL information
    *
    * @return dojo.Deferred;
    */
  this.getURLInfo = function()
  {
    var dfdInfo;
  
    // Timeout
    var t;
  
    // Canceller
    var c = function(dfd) {
      dfdInfo.cancel();
      clearTimeout(t);
    };
  
    // Deferred
    var d = new dojo.Deferred(c);
    
    // UID
    var uid = this.uid;
    
    // Info getter
    var p = function() {
  
      dfdInfo = dojo.xhrGet({
        url: '/api.php',
        content: {api: 'url_download', method: 'url_info', uid: uid},
        handleAs: 'json',
        preventCache: true
      });
  
      dfdInfo.addCallback(function(data) {
  
        if (data.error == consts.ERROR_OK)
        {
          d.callback(data);
        }
        else
        {
          t = setTimeout(p, 1000);
        }
  
      });
  
      dfdInfo.addErrback(function() { d.errback() });
  
    };
  
    p();
  
    return d;
  };
  
  /**
  * Download URL to server
  *
  * @return dojo.Deferred
  */
  this.download = function()
  {
    return dojo.xhrGet({
      url: '/api.php',
      content: {api: 'url_download', method: 'url_download', url: encodeURI(this.url), uid: this.uid},
      handleAs: 'json'
    });
  };
  
  /**
  * Cleanup url_downloader temp data
  *
  */
  this.cleanup = function()
  {
    return dojo.xhrGet({
      url: '/api.php',
      content: {api: 'url_download', method: 'url_cleanup'},
      handleAs: 'json'
    });
  };
  
  /**
  * Scan downloaded URL
  *
  */
  this.scan = function()
  {
    return dojo.xhrGet({
      url: '/api.php',
      content: {api: 'scan_file', method: 'scan_url', url_uid: this.uid},
      handleAs: 'json'
    });
  }
}

/**
  * Sacan URL for viruses
  *
  */
function scanURL()
{
  // Download url to server

  var url = dojo.byId('urlScan_text').value;
  var url_uid = hexUID(128);
  
  try
  {
    // Reset progress screen
    urlProgressBar.setPercent(0);
    dojo.byId('url_upload_status').innerHTML = 'Downloading...';
    dojo.byId('url_actualURL').innerHTML = '...';
    dojo.byId('url_fileSize').innerHTML = '...';
    dojo.byId('url_timePassed').innerHTML = '...';
    dojo.byId('url_timeLeft').innerHTML = '...';
    
    var scanner = new urlScanner(url, url_uid);
    var dfdDownload = scanner.download();
    var dfdShow2 = showScreen(2);
    
    dfdShow2.addCallback(function() {
  
      var dfdInfo = scanner.getURLInfo();
      var dfdProgress = scanner.getURLProgress();
  
      dfdProgress.showProgress = function(data) {
        if (data.error == consts.ERROR_OK) {
          urlProgressBar.setPercent(data.percent);
          dojo.byId('url_timePassed').innerHTML = data.time;
          dojo.byId('url_timeLeft').innerHTML = '~ ' + data.time_left;
       }};
  
      dfdInfo.addCallback(function(data) {
        dojo.byId('url_actualURL').innerHTML = data.url_actual;
        dojo.byId('url_fileSize').innerHTML = data.url_file_size;
      });
  
      // Download finished
      
      dfdDownload.addErrback(function() { 
        dfdProgress.cancel();
        dfdInfo.cancel();
      });
      
      dfdDownload.addCallback(function(data) {
        
        scanner.cleanup();
        dfdProgress.cancel();
        dfdInfo.cancel();
        
        if (data.error == consts.ERROR_OK)
        {
          urlProgressBar.setPercent(100);
          var dfdShow3 = showScreen(3);
          dfdShow3.addCallback(function() {
            
            // Scan downloaded URL
            var dfdScanURL = scanner.scan();
            
            dfdScanURL.addCallback(function(data) {
              
              // Display results
              if (data.error != consts.SCAN_OK)
              {
                // error
                alert(data.message);
                resetPage();
              }
              else
              {
                // display result
                dojo.byId('p2_s4_fileName').innerHTML = decodeURI(data.name);
                dojo.byId('p2_s4_fileStatus').innerHTML = data.result == consts.SCAN_OK ? 'Clean' : ('Infected with ' + data.infection);
                dojo.byId('p2_s4_fileMD5').innerHTML = data.md5;
                dojo.byId('p2_s4_fileSHA1').innerHTML = data.sha1;
          
                var dfdCert = showCert(data.md5, 'p2_s4_fileCert', 'p2_s4_certHTMLText');
                var dfdShow4 = showScreen(4);
          
                dfdShow4.addCallback(function(_cert_script) {
                  applyTheme(data.result == consts.SCAN_OK ? 'g' : 'r');
                  dfdCert.addCallback(function(_cert_script) { cert_timeout = setTimeout(function () { eval(_cert_script); }, 100); } );
                });
              }
            });
          });
        }
        else
        {
          dojo.byId('url_upload_status').innerHTML = 'Error!';
          alert("Can't download URL:\n" + data.message);
          resetPage();
        }
      });
    });
  }
  catch (e)
  {
    if (typeof dfdProgress != 'undefined') { dfdProgress.cancel(); }
    if (typeof dfdInfo != 'undefined') { dfdInfo.cancel(); }
    alert(e);
    resetPage();
  }
}

/**
  * Progress bar
  *
  */
var myProgressBar = function (progressBarNode)
{
  // Create progress bar from div
  progressBarNode.innerHTML = '<div class="progress_complete"></div><div class="progress_digits" align="center">0%</div>';
  progressBarNode.setAttribute('align', 'left');
  progressBarNode.className = 'progress_bg';
  
  this.node = progressBarNode;
  
  // Set percent value
  this.setPercent = function (percent) {
    for (var i = 0; i < this.node.childNodes.length; i++)
    {
      var n = this.node.childNodes[i];
      
      if (n.nodeType == 1)
      {
        if (n.className == 'progress_complete')
        {
          dojo.animateProperty({
            node: n,
            properties: {
              'width': {
                start: parseFloat(n.style.width||0),
                end: percent,
                units: '%'
            }},
            duration: 250,
            onEnd: function() { this.node.style.width = percent + '%' }
          }).play();
        }
        else if (n.className == 'progress_digits')
        {
          n.innerHTML = Math.round(percent) + '%';
        }
      }
    }
  }
};

// [Startup]

dojo.addOnLoad(init);

// xxx

//dojo.addOnLoad(function() {
//
//  showPage(2);
//  showScreen(2);
//  
//});
