/* Solar Jetman password generator / decoder
 * Copyright (C) 1992,2004 Joel Yliluoma (http://iki.fi/bisqwit/)
 * Written for http://tasvideos.org/PasswordGenerators.html
 * Permission to copy and modify is granted under the following terms:
 *   The copyright notice is kept unmodified
 *   No attempts are made to prevent anyone downloading the source code
 *
 * Checksum algorithm solved by Bisqwit with impulse from David Lawrence Ramsey.
 */
function solarjetinput(name)
{
  this.gel = function(id)   { return document.getElementById(name+id) }
  this.id  = function(id)   { return this.gel(id).selectedIndex }
  this.ids = function(id,v) { this.gel(id).selectedIndex=v }
  this.ch  = function(id)   { return this.gel(id).checked?1:0 }
  this.chs = function(id,v) { this.gel(id).checked = v>0 }
  this.tx  = function(id)   { return this.gel(id).value }
  this.txs = function(id,v) { this.gel(id).value = v }
  
  /* 0..15 values */
  this.nibbles = [0,0,0,0,0,0, 0,0,0,0,0,0]

  /*           0123456789ABCDEF */
  this.cset = 'BDGHKLMNPQRTVWXZ'

  this.updatedots = function()
  {
    s = ''
    t = this.cset
    for(n=0; n<12; ++n)
    {
      i = this.nibbles[n]&15
      s += t.charAt(i)
    }
    this.txs('l', s)
  }
  this.decode = function()
  {
    error   = 0
    message = ''
    
    l = this.tx('l')
    t = this.cset
    for(n=0; n<12; ++n)
    {
      this.nibbles[n ] = t.indexOf(l.charAt(n)) & 15
    }

    this.ids('life', this.nibbles[0])
    
    score=0
    n=this.nibbles[1]; if(n>9)n=9; score += n*1
    n=this.nibbles[4]; if(n>9)n=9; score += n*100
    n=this.nibbles[5]; if(n>9)n=9; score += n*10
    n=this.nibbles[6]; if(n>9)n=9; score += n*1000
    n=this.nibbles[7]; if(n>9)n=9; score += n*10000
    n=this.nibbles[11];if(n>9)n=9; score += n*100000    
    this.txs('score', score)
    
    this.ids('map',   this.nibbles[8]&3)
    this.ids('level', ((this.nibbles[8]>>2) + 4*this.nibbles[2]) & 63)
    
    this.chs('T', this.nibbles[10]&1) // boosters
    this.chs('S', this.nibbles[10]&2) // shields
    this.ids('ship',  this.nibbles[10]>>2)
    
    if(this.nibbles[3] != this.first_sum()
    || this.nibbles[9] != this.second_sum())
    {
      error=1
      message += 'Checksum failure; '
    }

    if(error)message = 'Error: ' + message
    this.txs('msg', message)
  }
  this.modified = function()
  {
    this.decode()
    this.setup()
  }
  this.get_sums = function()
  {
    var n4 = this.nibbles[0]*16 + this.nibbles[6] 
    var n5 = this.nibbles[1]*16 + this.nibbles[7] 
    var n6 = this.nibbles[2]*16 + this.nibbles[8] 
    var n8 = this.nibbles[4]*16 + this.nibbles[10]
    var n9 = this.nibbles[5]*16 + this.nibbles[11]
    var a = (n4^n5)+n6
    var carry = a >= 0x100
    a = (a^n8)+n9+carry
    return [(a >> 4)&15, a & 15]
  }
  this.first_sum = function()
  {
    var sums = this.get_sums()
    return sums[0]
  }
  this.second_sum = function()
  {
    var sums = this.get_sums()
    return sums[1]
  }
  this.setup = function()
  {
    score = 0 + this.tx('score')
    
    this.nibbles[0] = this.id('life')&15
    this.nibbles[1] = Math.floor(score /      1) %10
    this.nibbles[2] = (this.id('level') >> 2) & 15
    this.nibbles[4] = Math.floor(score /    100) %10
    this.nibbles[5] = Math.floor(score /     10) %10
    this.nibbles[6] = Math.floor(score /   1000) %10
    this.nibbles[7] = Math.floor(score /  10000) %10
    this.nibbles[8]  = (this.id('map') + 4*this.id('level')) & 15
    this.nibbles[10] = (this.ch('T')*1 + this.ch('S')*2 + this.id('ship')*4) & 15
    this.nibbles[11]= Math.floor(score / 100000) %10
    
    this.nibbles[3] = this.first_sum()
    this.nibbles[9] = this.second_sum()
    
    this.updatedots()
    this.decode()
  }
}
