
var nospace = "<span class=nospace></span>";
var space = " ";

var diacmark1 = '"';
var diacmark2 = 'º';
var anystroke = '+';
var nostroke  = '.';
var exactPos  = '=';
var anyPos    = '±';
var nomatch   = '-';

var nperline = 5; // number of matching-strokes kana per line

var fullTable = false;
var viewChart = true;
var textBox = false;
var zooming = false;
var hira1st = true;
var exactly = true;
var nstroke = 0;

var kasataha = 1;
var proximity = 0;
var ksthmode = 1; 
var proxmode = 2;
var highlight = ksthmode;   // highlight modes are 0 (none),  1 (KSTH / KGWA) and (proximity) 

var showhira,showkata,showroma,hiraset,kataset,stroked;

function noZoom() { 
 zooming = false;
 document.getElementById('area6').innerHTML = '<span class="tiny">&nbsp</span>'; 
}

function hiraZoom(x) {
 if (zooming) noZoom();
 else {
  document.getElementById('area6').innerHTML = '<div class="modal"><span class="hirazoom" onClick="noZoom()">'+x+'</span></div>';
  zooming = true;
 }
}

function kataZoom(x) {
 if (zooming) noZoom();
 else {
  document.getElementById('area6').innerHTML = '<div class="modal"><span class="katazoom" onClick="noZoom()">'+x+'</span></div>';
  zooming = true;
 }
}

function hiraStrokes(x) {
var i,s,ref;

  s = '';
  ref = hira[x];
  if (ref==undefined) return; // monographs or diacritic, ignore digraphs
  for(i=1;i<ref.length;i++) s+= nbsp+strokes[ref[i]];
  if (hdiacs1.indexOf(x)>=0) s+= nbsp+diacmark1; else if (hdiacs2.indexOf(x)>=0) s+= nbsp+diacmark2;  
  s += nbsp+'<span class="romatext" onClick="clearRomaji()">'+ref[0]+'</span>';
  document.getElementById('area2').innerHTML = '<span class="hiralight" onClick="hiraZoom('+"'"+x+"'"+')">'+x+'</span><span class="stroked">'+s+'</span>';
}

function kataStrokes(x) {
var i,s,ref;
  
  s = '';
  ref = kata[x];
  if (ref==undefined) return; // monographs or diacritic, ignore digraphs
  for(i=1;i<ref.length;i++) if (ref[i]) s+= nbsp+strokes[ref[i]];
  if (kdiacs1.indexOf(x)>=0) s+= nbsp+diacmark1; else if (kdiacs2.indexOf(x)>=0) s+= nbsp+diacmark2;  
  s += nbsp+'<span class="romatext" onClick="clearRomaji()">'+ref[0]+'</span>';
  document.getElementById('area2').innerHTML = '<span class="katalight" onClick="kataZoom('+"'"+x+"'"+')">'+x+'</span><span class="stroked">'+s+'</span>';
}


function matching(r,ref,stroke) {
var h,n;

  n = nstroke+1;
  if (n==ref.length) return (stroke==0);
  else if (n>ref.length) return false;
  else if (exactly) {
   if (stroke<0) return true; else return (ref[n] == stroke);
  }
  else if (stroke<0) return true;
  else {
   for(h=1;h<ref.length;h++) if (ref[h]==stroke) return true;
   return false;
  }
}

function matchHira(stroke) {
var f,r,s,i,j,k;
 //
 // search matching hiraganas 
 //
 s=hiraset;
 f = '';
 for(i=j=0;i<s.length;i++) {
  k = s.charAt(i);
  ref = hira[k];
  r = ref[0];
  if (matching(r,ref,stroke)) f+=k;
 }
 hiraset = f;
}

function matchKana(stroke) {
var f,r,s,i,j,k;
 //
 // search matching katakanas 
 //
 s = kataset;
 f = '';
 for(i=j=0;i<s.length;i++) {    // for (var k in kata)
  k = s.charAt(i);
  ref = kata[k];
  r = ref[0];
  if (matching(r,ref,stroke)) f+=k;
 }
 kataset = f;
}

function matchStroke(stroke) {
 if (nstroke==0) stroked='';
 if (stroke<0) stroked+=anystroke; else stroked+=strokes[stroke];
 matchHira(stroke);
 matchKana(stroke);
 if (stroke) nstroke++; else nstroke=0;
 document.getElementById('area3').innerHTML = stroked;
 setGroup(0);
 kasataha = 0;
 highlight = 0;
 drawTable(0);
}

function toggleProximity() {
 if (getGroup()) return; // ignore cases other than displaying monographs
 showhira = document.fform.hiragana.checked;
 showkata = document.fform.katakana.checked;
 if ((showkata) && (showhira)) document.fform.katakana.checked = showkata = false;
 if (highlight==proxmode) proximity = (++proximity) % 13;
 highlight = proxmode;
 drawTable(proxmode);
}

function toggleBackground() {
 if (getGroup()) return; // ignore cases other than displaying monographs
 if (highlight==ksthmode) kasataha = (++kasataha) % 3;
 highlight = ksthmode;
 drawTable(ksthmode);
}

function drawStrokes() {
var i,s,mode;

  if (exactly) mode = exactPos; else mode= anyPos;
  s = "<table border=1 cellpadding=0 cellspacing=0><tr>";
  for(i=1;i<5;i++) s += '<td align=center class=strokes onClick="matchStroke('+ i + ')">'+strokes[i]+'</td>';
  s+= '<td align=center class=xstroke onClick="matchStroke(-1)">'+anystroke+'</td>';
  s+= '<td align=center class=xstroke onClick="matchStroke(0)">'+nostroke+'</td>';
  s+= '<td align=center class=reset onClick="toggleStrokesMode()">'+mode+'</td>';
  s+= '<td align=center class=reset onClick="initStrokes()">x</td>';
  s+= '<td align=center class=ksthkw onClick="toggleBackground()"></td>';
  s+= '<td align=center class=hkprox onClick="toggleProximity()"></td>';
  s+= "</tr></table>";
  document.getElementById('area1').innerHTML = s;
}

function toggleStrokesMode() {
 exactly = !exactly;
 initStrokes();
 drawTable(0);
}

function initStrokes() {
 resetStrokes();
 drawStrokes();
 drawTable(ksthmode);
}

function resetStrokes() {
 nstroke = 0;
 hiraset=hiraganas; 
 kataset=katakanas;
 clearScreen();
}

function clearScreen() { for (var i=1;i<6;i++) document.getElementById('area'+i).innerHTML = nospace; }

function clearInput() {
 document.fform.hiraline.value = '';
 document.fform.kataline.value = '';
 // document.getElementById('area1').innerHTML = nospace;
}

function setGroup(n) { document.fform.group[n].checked = true; }

function getGroup() {
 for (var i=0; i < document.fform.group.length; i++) {
   if (document.fform.group[i].checked) return i;
   // var v = document.fform.group[i].value;
 }
 return -1;
}

/*
function typeIn(j,i,n) {
var a,b;

 if (i<0) typeInIf(j,n);
 else {
  switch(n) {
   case 0:  // Monographs (gojūon)
    a = hmono[j][i]; b = kmono[j][i];
    break;
   case 1:  // Diacritics (gojūon with (han)dakuten)
    a = hdiac[j][i]; b = kdiac[j][i];
    break;
   case 2:  // Digraphs (yōon) 
    a = hdigr[j][i]; b = kdigr[j][i];
    break;
   case 3:  // Digraphs with diacritics (yōon with (han)dakuten)
    a = hdidi[j][i]; b = kdidi[j][i];
   //  break;
   // default : ;
  }
  document.fform.hiraline.value += a;
  document.fform.kataline.value += b;
  document.fform.hiraline.focus();
  // document.fform.hiraline.select();
 }
}
*/
            
function typeInIf(j,n) {
var a,b;

 a=b='';
 switch(n) {
  case 0:  // Monographs (gojūon)
        if (j==0) { a = hmonox[1]; b = kmonox[1]; }
   else if (j==9) { a = hmonox[0]; b = kmonox[0]; }
   else return;
   break;
  case 1:  // Diacritics (gojūon with (han)dakuten)
   return;
  case 2:  // Digraphs (yōon) 
   if (j>1) return; else {a = hdigrx[0]; b = kdigrx[0];}
   break;
  case 3:  // Digraphs with diacritics (yōon with (han)dakuten)
   if (j>1) return; else {a = hdigrx[1]; b = kdigrx[1];}
  //  break;
  // default : ;
 }
 document.fform.hiraline.value += a;
 document.fform.kataline.value += b;
 document.fform.hiraline.focus();
}

function typeIf(j,n) {
var a,b,c;

 a=b=c='';
 switch(n) {
  case 0:  // Monographs (gojūon)
   if (j==0) {
    if (showkata) { a = hmonox[1]; b = rmonox[1]; c = kmonox[1]; }
    else break;
   }
   else if (j==9) { a = hmonox[0]; b = rmonox[0]; c = kmonox[0]; }
   break;
  case 1:  // Diacritics (gojūon with (han)dakuten)
   break;
  case 2:  // Digraphs (yōon) 
   if (j>1) break; else {a = hdigrx[0]; b = rdigrx[0]; c = kdigrx[0];}
   break;
  case 3:  // Digraphs with diacritics (yōon with (han)dakuten)
   if (j>1) break; else {a = hdigrx[1]; b = rdigrx[1]; c = kdigrx[1];}
  //  break;
  // default : ;
 }
 d='';
 if ((a.length) && (b.length) && (c.length)) {
  if (showhira) d+= hiraLink(n,a);
  if (showkata) d+= space + kataLink(n,c);
  if (showroma) {
   if ((!showhira) && (!showkata)) d+=space; else if (n>1) d+= "<br />"; else d+=space;
   d+= romaLink(b,-1,j,n); 
  }
 }
 else d=nospace;
 return d;
}

function hiraLink(n,x) {
var cl;

 if ((n==0) && (x!='.') && (hiraset.indexOf(x)<0)) cl = 'hiragrey'; else cl = 'hiragana';
 return '<span class="' + cl + '" onClick=hiraStrokes("'+x+'")>'+x+' </span>';
}

function kataLink(n,x) {
var cl;

 if ((n==0) && (x!='.') && (kataset.indexOf(x)<0)) cl = 'katagrey'; else cl = 'katakana';
 return '<span class="' + cl + '" onClick=kataStrokes("'+x+'")>'+x+' </span>';
}

// function romaLink(c,i,j,n) { return '<span class=romaji onClick=typeIn('+j+','+i+','+n+')>'+c+'</span>'; }
function romaLink(c,i,j,n) { return '<span class=romaji >'+c+'</span>'; }

function getCell(n,i,j) {
var a,b,c,d;

 switch(n) {
 case 0:  // Monographs (gojūon)
  a = hmono[j][i]; b = kmono[j][i]; c = rmono[j][i];
  break;
 case 1:  // Diacritics (gojūon with (han)dakuten)
  a = hdiac[j][i]; b = kdiac[j][i]; c = rdiac[j][i];
  break;
 case 2:  // Digraphs (yōon) 
  a = hdigr[j][i]; b = kdigr[j][i]; c = rdigr[j][i];
  break;
 case 3:  // Digraphs with diacritics (yōon with (han)dakuten)
  a = hdidi[j][i]; b = kdidi[j][i]; c = rdidi[j][i];
 //  break;
 // default : ;
 }
 d='';
 if ((a.length) && (b.length) && (c.length)) {
  if (showhira) d+= hiraLink(n,a);
  if (showkata) d+= space + kataLink(n,b);
  if (showroma) {
   if ((!showhira) && (!showkata)) d+=space; else if (n>1) d+= "<br />"; else d+=space;
   d+= romaLink(c,i,j,n); 
  }
 }
 else d=nospace;
 return d;
}

function matchProximity(n,i,j) {
var a,b,g,r;

 if (n) return false;   // only check Monographs (gojūon) where n==0
 if (showhira) {
   a = hmono[j][i]; 
   if (a.length) {
     r=hprox[proximity];
     for(g=0;g<r.length;g++) if (a==r[g]) return true;
   }
 }
 else if (showkata) {
   b = kmono[j][i];
   if (b.length) {
     r=kprox[proximity];
     for(g=0;g<r.length;g++) if (b==r[g]) return true;
   }
 }
 return false;
}

function loadTable(n,mode) {
var i,j,k,c,s,imax,jmax;
var ksth,kgwa,kuwa,nimi;

  switch(n) {
   case 0: imax=5; jmax=hmono.length; break;  // Monographs (gojūon)
   case 1: imax=5; jmax=hdiac.length; break;  // Diacritics (gojūon with (han)dakuten)
   case 2: imax=3; jmax=hdigr.length; break;  // Digraphs (yōon) 
   case 3: imax=3; jmax=hdidi.length; break;  // Digraphs with diacritics (yōon with (han)dakuten)
  }
  s = "<table border=1 cellpadding=0 cellspacing=0><tr>";
  for (j=0;j<jmax;j++) {
    tdclass='spacer';
    if (mode==proxmode) {       // match proximity
      if (j==(jmax-1))
        if ((showhira && (proximity==11)) || (showkata && (proximity==9))) tdclass='prox';
    }
    s += '<tr><td align=center class="'+tdclass+'" id=k"'+j+'0"'+n;
    if ((j>0)&&(j<jmax-1)) s += ' onClick="toggleTableMode()"></td>'; else s+='>'+typeIf(j,n)+'</td>' ;
    for (i=0;i<imax;i++) {
      tdclass='spacer';
      if (n==0) {
        if (mode==ksthmode) {
          ksth = (j==1)||(j==2)||(j==3)||(j==5);
          kgwa = (j==7) || ((i==1) && ((j==7) || ksth));
          kuwa = ((i==0)&&(j==9)) || ((i==2)&&(j==1));
          nimi = (i==1) && ((j==4)||(j==6));
               if (ksth && (kasataha==1)) tdclass='ksth';
          else if (kgwa && (kasataha==2)) tdclass='kgwa';
          else if (kuwa && (kasataha==2)) tdclass='kuwa';
          else if (nimi && (kasataha==2)) tdclass='nimi';
        }
        else if (mode==proxmode) {       // match proximity
          if (matchProximity(n,i,j)) tdclass='prox';
        }
      }
      s += '<td align=center class="' + tdclass + '" id="c'+j+i+n+ '">'+ getCell(n,i,j) +'</td>';
    }
    s += "</tr>\n";
  }
  s+= "</table>";
  return s;
}

function drawTable(mode) {
var i,j,k,c,n,s,max;

  showhira = document.fform.hiragana.checked;
  showkata = document.fform.katakana.checked;
  showroma = document.fform.romaji.checked;
  if ((!showkata) && (!showhira) && (!showroma)) document.fform.hiragana.checked = showhira = true;
  n = getGroup();
  if (fullTable || ((showroma) && (!showkata) && (!showhira))) {
   if (n<2) n=0; else n=2;
   document.getElementById('area3').innerHTML = loadTable(n,mode);
   document.getElementById('area4').innerHTML = loadTable(++n,0);
  }
  else {
   document.getElementById('area3').innerHTML = loadTable(n,mode);
   document.getElementById('area4').innerHTML = nospace;
  }
}

function toggleTableMode() {
 fullTable = !fullTable;
 drawTable(1);
}
             
function clearRomaji() {
 document.getElementById('area2').innerHTML = nospace; 
}
             
function showHelp() { document.getElementById('area3').innerHTML=helptext; }
