/* Mega Man 5 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
 *
 * Reverse engineering by unknown, documentation from Protoman's site
 */
function mm5input(name)
{
  this.grps =
  [
    /* red dots, blue dots. blue uses red's slot if red does not use it. */
    /* all positions are verified to be correct */
    /* basic binary pattern: --- a-- -b- ab- --c a-c -bc abc */
    /* note: incidentally, vertical number-positions are always same */
    
    [6*6+5, 3*6+6, 2*6+6, 1*6+5, 2*6+5, 1*6+6, 3*6+5, 6*6+6, 'GR','WA','SO'],
    [5*6+5, 5*6+6, 5*6+6, 5*6+5, 4*6+5, 4*6+6, 4*6+5, 4*6+6, 'M1','E', 'G'],

    [4*6+3, 1*6+4, 6*6+4, 5*6+3, 6*6+3, 5*6+4, 1*6+3, 4*6+4, 'GY','ST','CH'],
    [2*6+3, 3*6+4, 3*6+4, 2*6+3, 3*6+3, 2*6+4, 3*6+3, 2*6+4, 'A1','M2','A2'],

    [2*6+1, 5*6+2, 4*6+2, 3*6+1, 'NA','CR'],
    [6*6+1, 1*6+2, 1*6+2, 6*6+1, 'N', 'V']
  ]
               
  this.status=[0,0,0,0,0,0,
               0,0,0,0,0,0,
               0,0,0,0,0,0,
               0,0,0,0,0,0,
               0,0,0,0,0,0,
               0,0,0,0,0,0]

  this.gel = function(id)   { return document.getElementById(name+id) }
  this.id  = function(id)   { return this.gel(id).selectedIndex }
  this.ch  = function(id)   { return this.gel(id).checked }
  this.chs = function(id,v) { this.gel(id).checked=v>0 }
  this.view= function(id,v) { this.gel(id).style.visibility = v?'visible':'hidden' }
  this.img = function(id,v) { this.gel(id).src = v }
  
  this.updatedots = function()
  {
    files = ['css/black.png', 'css/red.png', 'css/blue.png']
    for(n=0;n<36;++n)
    {
      s = this.status[n]
      this.img('d'+n, files[s])
    }
  }
  
  this.decodehelper = function(n)
  {
    grp1  = this.grps[n*2  ]
    grp2  = this.grps[n*2+1]
    
    size  = n == 2  ? 2 : 3
    max   = size==2 ? 4 : 8
    
    a=-1
    b=-1
    for(n=0; n<max; ++n)
    {
      p1 = this.status[grp1[n]-7]
      p2 = this.status[grp2[n]-7]
      
      if(p1 == 1)
      {
        if(a==-1){a=n;}else{error=1;}
      }
      if(p1 == 2 || (p2 == 2 && p1 == 1))
      {
        if(b==-1){b=n;}else{error=1;}
      }
    }
    if(a==-1 || b==-1) { return 1 }
    
    if(size == 2)
    {
      this.chs(grp1[4], a&1); this.chs(grp2[4], b&1)
      this.chs(grp1[5], a&2); this.chs(grp2[5], b&2)
    }
    else
    {
      this.chs(grp1[8], a&1); this.chs(grp2[8], b&1)
      this.chs(grp1[9], a&2); this.chs(grp2[9], b&2)
      this.chs(grp1[10],a&4); this.chs(grp2[10],b&4)
    }

    return error
  }
  this.encodehelper = function(n)
  {
    grp1  = this.grps[n*2  ]
    grp2  = this.grps[n*2+1]
    
    size  = n == 2 ? 2 : 3
    
    if(size == 2)
    {
      pos1 = this.ch(grp1[4])*1 + this.ch(grp1[5])*2
      pos2 = this.ch(grp2[4])*1 + this.ch(grp2[5])*2
    }
    else
    {
      pos1 = this.ch(grp1[8])*1 + this.ch(grp1[9])*2 + this.ch(grp1[10])*4
      pos2 = this.ch(grp2[8])*1 + this.ch(grp2[9])*2 + this.ch(grp2[10])*4
    }

    pos2 = pos1==pos2 ? grp2[pos2] : grp1[pos2]
    pos1 = grp1[pos1]
    
    this.status[pos1-7] = 1
    this.status[pos2-7] = 2
  }
  
  this.decode = function()
  {
    error = 0
    
    dotcount=0
    for(n=0; n<36; ++n) if(this.status[n]) ++dotcount
    if(dotcount != 6) error=1

    for(n=0;n<3;++n) error += this.decodehelper(n)
    
    this.view('error', error)
  }
  this.hitdot = function(n)
  {
    s = (this.status[n]+1) % 3
    this.status[n]=s

    this.updatedots()
    this.decode()
  }
  
  this.setup = function()
  {
    for(n=0;n<36;++n) this.status[n]=0
    
    for(n=0;n<3;++n) this.encodehelper(n)

    this.updatedots()
    this.decode()
  }
}
