/*
   Yomukanji
   Copyright 2005-2006 Flavio Chierichetti
   Licence: GPL 2
*/

function isKanji(string, i) {
  var codepoint;

  codepoint = string.charCodeAt(i);

  if ( (0x3000 <= codepoint && codepoint <= 0x30FF) ||
       (0xFF00 <= codepoint && codepoint <= 0xFFFF) ||
       (codepoint <= 0x0FFF) )
    // Hiragana, Katakana, Punctuation || Small Katakana, Punctuation || Western
    return false;
  else
    // Hopefully Kanji
    return true;
}

function getKanjis(list) {
  var k, i, j, first;

  k = "";
  for ( i = 0 ; i < list.length ; i++ )
    if ( isKanji(list, i) ) {
      first = true;

      for ( j = 0 ; first && j < i ; j++ )
        if ( list.charAt(i) == list.charAt(j) )
          first = false;

      if ( first )
        k = k + list.charAt(i);
    }

  return k;
} 

function getBackReference() {
  var i, j, k, l;
  var s, c, br;

  br = new Array();

  for ( i = 0 ; i < contents["unit"].length ; i++ )
    for ( j = 0 ; j < contents["unit"][i]["card"].length ; j++ ) {

      s = contents["unit"][i]["card"][j]["kanji"];
      for ( l = 0 ; l < s.length ; l++ )
        if ( isKanji(s, l) ) {
          c = s.charAt(l);

          if ( typeof(br[c]) != 'undefined' &&
               br[c][br[c].length - 1]["unit"] == i &&
               br[c][br[c].length - 1]["card"] == j )
            continue;

          if ( typeof(br[c]) == 'undefined' ) br[c] = new Array();
          br[c][br[c].length] = {"unit": i, "card": j};
        }  

      for ( k = 0 ; k < contents["unit"][i]["card"][j]["subcard"].length ; k++ ) {

        s = contents["unit"][i]["card"][j]["subcard"][k]["kanji"];
        for ( l = 0 ; l < s.length ; l++ )
          if ( isKanji(s, l) ) {
            c = s.charAt(l);

            if ( typeof(br[c]) != 'undefined' &&
                 br[c][br[c].length - 1]["unit"] == i &&
                 br[c][br[c].length - 1]["card"] == j &&
                 br[c][br[c].length - 1]["subcard"] == k )
              continue;

            if ( typeof(br[c]) == 'undefined' ) br[c] = new Array();
            br[c][br[c].length] = {"unit": i, "card": j, "subcard": k};
          }  
      }
    }

  return br;
}

/* ---------- */

function isIE() {
  return document.all && !window.opera;
}

/* ---------- */

function cleanPage() {
  removeChildren( document.getElementsByTagName("body")[0] );
}

function removeChildren(e) {
  while ( e.firstChild != null )
    e.removeChild(e.firstChild);
}

function hasClass(e, cn) {
  var regexp;

  if ( isIE() ) {
    regexp = new RegExp("(^|\\s)" + cn + "(\\s|$)");
    return regexp.test(e.className);
  } else {
    return e.getAttribute('class') == cn;
  }
}

function setAttribute(element, attribute, value) {
  var st, a, b, i;

  if ( isIE() ) {
    if ( attribute == 'onClick' ) {
      element.onclick = new Function(value);
    } else if ( attribute == 'onMouseOver' ) {
      element.onmouseover = new Function(value);
    } else if ( attribute == 'onMouseOut' ) {
      element.onmouseout = new Function(value);
    } else if ( attribute == 'style' ) {
      element.setAttribute('cssText', value);
    } else if ( attribute == 'class' ) {
      element.className = value;
    } else if ( attribute == 'id' ) {
      element.id = value;
    } else if ( attribute == 'href' ) {
      element.href = value;
    } else if ( attribute == 'src' ) {
      element.src = value;
    } else if ( attribute == 'font-size' ) {
      element.style.fontSize = value;
    } else {
      element.setAttribute(attribute, value);
    }
  } else {
    if ( attribute == 'font-size' ) {
      st = element.getAttribute('style');
 
      if ( st == null )
        st = '';

      /* Deleting previous font-size declaration */
      if ( st.indexOf(attribute + ':') != -1 ) {
        a = st.indexOf(attribute + ':');
        b = st.indexOf(';', a);
        if ( b == -1 )
          b = st.length - 1;
 
        st = st.substring(0, a) + st.substring(b + 1, st.length);
      }

      /* Making sure that the attribute ends with a ';' */
      for ( i = st.length - 1 ; i >= 0 ; i++ )
        if ( st.charAt(i) == ';' )
          break;
        else if ( st.charAt(i) == ' ' || st.charAt(i) == '\t' || st.charAt(i) == '\n' )
          continue;
        else {
	  st += ';'
        }

      /* Adding the font-size */
      st += attribute + ': ' + value

      element.setAttribute('style', st);
    } else {
      element.setAttribute(attribute, value);
    }
  } 
}

/* ---------- */

function createAnchor(text, uri) {
  var a;

  a = document.createElement("a");
  setAttribute(a, "href", uri);
  a.appendChild( document.createTextNode(text) );

  return a;
}

function createEMailAnchor(name, u, d) {
  return createAnchor(name, "mailto:" + u + "@" + d);
} 

function createEMailAnchorSubject(name, u, d, subject) {
  return createAnchor(name, "mailto:" + u + "@" + d + "?subject=" + subject);
} 

function createHeader() {
  var header, text, a, b, c;

  header = document.createElement("div");
  header.setAttribute("id", "headert");
  header.setAttribute("style", "margin: 5mm");

  a = document.createElement("span");
  setAttribute(a, "font-size", "25pt");
  text = document.createTextNode(contents["title"]);
  a.appendChild(text);
  header.appendChild(a);
  header.appendChild(document.createElement("br"));

  /*
  b = document.createElement("span");
  setAttribute(b, "font-size", "20pt");
  text = document.createTextNode(contents["author"]);
  b.appendChild(text);
  header.appendChild(b);
  header.appendChild(document.createElement("br"));
  */

  c = document.createElement("span");
  setAttribute(c, "font-size", "15pt");
  text = document.createTextNode(contents["version"]);
  c.appendChild(text);

  header.appendChild(c);

  return header;
}

function createFooter() {
  var footer, p;

  footer = document.createElement("div");
  setAttribute(footer, "id", "footer");

  p = document.createElement("p");
  setAttribute(p, "font-size", "10pt");
  p.appendChild( document.createTextNode("I test di questo programma sono © " + contents["author"] + ".") );
  p.appendChild( document.createElement("br") );
  p.appendChild( document.createTextNode("Il programma è © ") );
  p.appendChild( createEMailAnchor("Flavio Chierichetti", "yomukanji", "lightless.org") );
  p.appendChild( document.createTextNode(" ed è rilasciato liberamente secondo i termini della licenza GPL 2.") );
  p.appendChild( document.createElement("br") );
  p.appendChild( document.createTextNode("Aggiornato " + contents["date"] + ". Nuove versioni saranno disponibili ") );
  p.appendChild( createAnchor("qui", "http://lightless.org/yomukanji") );
  p.appendChild( document.createTextNode(".") );

  footer.appendChild(p);

  return footer;
}

function createTitle(t, doc) {
  var a;

  a = doc.createElement("span");
  setAttribute(a, "class", "title");
  a.appendChild(doc.createTextNode(t));

  return a;
}

function createMegaKanjiSpan(k, doc, id, pik, sc, mouse) {
  var a, j, span;

  a = doc.createElement("span");
  setAttribute(a, "font-size", "60pt");

  for ( j = 0 ; j < k.length ; j++ ) {
    span = doc.createElement("span");
    if ( sc == null ) {
      setAttribute(span, "id", "meaning-" + id + "-" + pik + "-" + j);
    } else {
      setAttribute(span, "id", "meaning-" + id + "-" + pik + "-" + sc + "-" + j);
    } 

    setAttribute(span, "onMouseOver", "lightOn(" + id + "," + pik + "," + sc + "," + j + ",this)");
    setAttribute(span, "onMouseOut", "lightOff(" + id + "," + pik + "," + sc + "," + j + ",this)");

    span.appendChild( doc.createTextNode(k.charAt(j)) );

    // Ugly IE 5.5 hack
    if ( typeof(span.ownerDocument) == 'undefined' )
      span.ownerDocument = doc;

    a.appendChild( span );
  }

  return a;
}

function lightOn(id, pik, sc, j, origin) {
  var doc, elem, par, cl, count, i;
  
  doc = origin.ownerDocument;
  elem = doc.getElementById("meaning-" + id + "-" + pik + "-" + (sc != null ? sc + "-" : "") + j);

  for ( par = elem ;
	!hasClass(par, 'main') && !hasClass(par, 'right') && !hasClass(par, 'wrong') ;
	par = (typeof(par.parentNode) == 'undefined') ? par.parentElement : par.parentNode );

  if ( hasClass(par, 'main') )
    cl = 'mainOn';
  else if ( hasClass(par, 'right') )
    cl = 'rightOn';
  else if ( hasClass(par, 'wrong') )	
    cl = 'wrongOn';

  setAttribute(elem, 'class', cl);

  cl += "Underline";

  for ( count = 0 ;
        doc.getElementById("meaning-" + id + "-" + pik + "-" + (sc != null ? sc + "-" : "") + count + "-0-" + j) != null ;
	count++ ) {
    for ( i = 0 ;
	  (elem = doc.getElementById(
		"meaning-" + id + "-" + pik + "-" + (sc != null ? sc + "-" : "") + count + "-" + i + "-" + j)) != null ;
	  i++ )
      setAttribute(elem, 'class', cl);
  }
}

function lightOff(id, pik, sc, j, origin) {
  var doc, elem, count, i;

  doc = origin.ownerDocument;
  elem = doc.getElementById("meaning-" + id + "-" + pik + "-" + (sc != null ? sc + "-" : "") + j);
  
  setAttribute(elem, 'class', '');

  for ( count = 0 ;
        doc.getElementById("meaning-" + id + "-" + pik + "-" + (sc != null ? sc + "-" : "") + count + "-0-" + j) != null ;
	count++ )
    for ( i = 0 ;
	  (elem = doc.getElementById(
		"meaning-" + id + "-" + pik + "-" + (sc != null ? sc + "-" : "") + count + "-" + i + "-" + j)) != null ;
	  i++ )
      setAttribute(elem, 'class', '');
}

function createFalseLink(text, href) {
  var a, child;

  a = document.createElement("span");
  setAttribute(a, "class", "hov");
  setAttribute(a, "onClick", href);
  child = document.createTextNode( text );
  a.appendChild(child);

  return a;
}

function createMeaningSpan(meaning, doc, id, pik, sc, count) {
  var m, i, j, span;
 
  m = doc.createElement("span");
  setAttribute(m, "font-size", "20pt");

  for ( i = 0 ; i < meaning["yomi"].length ; i++ ) {
    for ( j = 0 ; j < meaning["yomi"][i].length ; j++ ) {
      span = doc.createElement("span");

      if ( sc == null )
        setAttribute(span, "id", "meaning-" + id + "-" + pik + "-" + count + "-" + i + "-" + j );
      else
        setAttribute(span, "id", "meaning-" + id + "-" + pik + "-" + sc + "-" + count + "-" + i + "-" + j );

      span.appendChild( doc.createTextNode(meaning["yomi"][i][j]) );

      m.appendChild( span );
    }

    if ( i < meaning["yomi"].length - 1 )
      m.appendChild( doc.createTextNode("\u3001") );
  }
  
  m.appendChild( doc.createTextNode(" - " + meaning["meaning"]) );

  return m;    
}

function createSubcard(subcard, doc, id, pik, sc) {
  var subdiv, m, meaning, count;

  subdiv = doc.createElement("div");
  setAttribute(subdiv, "class", "subcard");

  m = createMegaKanjiSpan(subcard["kanji"], doc, id, pik, sc);
  setAttribute(m, "font-size", "20pt");

  subdiv.appendChild(m);
  subdiv.appendChild( doc.createElement("br") );

  var meaning = subcard["meaning"];
  for ( count = 0 ; count < meaning.length ; count++ ) {
    m = createMeaningSpan(meaning[count], doc, id, pik, sc, count);
    setAttribute(m, "font-size", "15pt");

    subdiv.appendChild(m);
    subdiv.appendChild( doc.createElement("br") );
  }

  return subdiv;
}

function createRadicalSubcard(kanji, heading, doc) {
  var subdiv, string, r;

  subdiv = null;

  for ( radical in contents["radicals"] )
    if ( contents["radicals"][radical]["kanjilist"].indexOf( kanji ) != -1 ) {
      if ( subdiv == null ) {
        subdiv = doc.createElement("div");
        setAttribute(subdiv, "class", "subcard");

        if ( heading ) {
          m = doc.createElement("span");
          setAttribute(m, "font-size", "20pt");
          m.appendChild( doc.createTextNode( "Radicali di " + kanji ) );
   
          subdiv.appendChild(m);
          subdiv.appendChild( doc.createElement("br") );
        }
      }

      string = radical;
      if ( contents["radicals"][radical]["meaning"] != "" ) {
        string += " - " + contents["radicals"][radical]["meaning"];

        if ( contents["radicals"][radical]["yomi"] != "" )
          string += " (" + contents["radicals"][radical]["yomi"] + ")";
      }

      r = doc.createElement("span");
      r.appendChild( doc.createTextNode(string) );

      subdiv.appendChild(r);
      subdiv.appendChild( doc.createElement("br") );
    }

  return subdiv;
}

function createNote(card) {
  var subdiv, text;

  subdiv = document.createElement("div");
  setAttribute(subdiv, "class", "note");
  if ( card["kaku"] ) {
    subdiv.appendChild( document.createTextNode(contents["kaku"]) );

    if ( card["note"] != "" )
      subdiv.appendChild( document.createElement("br") );
  }
  text = document.createTextNode(card["note"]);
  subdiv.appendChild( text );

  return subdiv;
}

function createWwwjdic(card) {
  var jdicdiv, jdicspan, jdica, list, j;

  jdicdiv = document.createElement("div");
  setAttribute(jdicdiv, "class", "cardlinks");

  jdicspan = document.createElement("span");
  jdicspan.appendChild( document.createTextNode("Clicka su un Kanji per visualizzarne l'ordine dei tratti su ") );
  setAttribute(jdicspan, "font-size", "10pt");

  jdica = document.createElement("a");
  setAttribute(jdica, "onClick", "javascript:window.open(\"" + strokes["wwwjdic"]["mirror"][options["dic"]]["home"] + "\", \"external\").focus(); return false;");
  setAttribute(jdica, "href", strokes["wwwjdic"]["mirror"][options["dic"]]["home"]);
  setAttribute(jdica, "target", "external");
  jdica.appendChild( document.createTextNode("WWWJDIC") );
  jdicspan.appendChild( jdica );

  jdicdiv.appendChild( jdicspan );
  jdicdiv.appendChild( document.createElement("br") );

  list = card["kanji"];

  for ( j = 0 ; j < card["subcard"].length ; j++ )
    list = list + card["subcard"][j]["kanji"];

  if ( appendStrokesLinks(jdicdiv, getKanjis(list)) )
    return jdicdiv;
  else
    return null;
}

function getStrokesLink(character, libId) {
  var c;

  if ( typeof(strokes[libId]['mirror'][options['dic']]) == 'undefined' )
    return '';

  if ( typeof(strokes[libId]['hash'][character]) != 'undefined' )
    c = strokes[libId]['hash'][character];
  else
    c = character;

  return strokes[libId]['mirror'][options['dic']]['prefix'] + c + strokes[libId]['mirror'][options['dic']]['suffix'];
}

function isPicture(libId) {
  if ( typeof( strokes[libId]['mirror'][options['dic']] ) == 'undefined' )
    return false;
  else
    return strokes[libId]['mirror'][options['dic']]['suffix'].match("[.](gif|png)$");
}

function appendStrokesLinks(div, string) {
  var empty, i, character, child, href;

  empty = true;

  for ( i = 0 ; i < string.length ; i++ ) {
    character = string.charAt(i);

    if ( !empty )
      div.appendChild(document.createTextNode(" - "));
    else
      empty = false;

    child = document.createElement("a");
    child.appendChild(document.createTextNode(character));

    href = getStrokesLink(character, 'wwwjdic');

    setAttribute(child, "onClick", "javascript:window.open(\"" + href + "\", \"external\").focus(); return false;");
    setAttribute(child, "href", href);
    setAttribute(child, "target", "external");

    div.appendChild(child);
  }

  return !empty;
}

function createRef(card) {
  var jdicdiv, jdicspan, list, j;

  jdicdiv = document.createElement("div");
  setAttribute(jdicdiv, "class", "cardlinks");

  jdicspan = document.createElement("span");
  jdicspan.appendChild( document.createTextNode("Clicka su un Kanji per visualizzarne le occorrenze nelle diverse unità.") );
  setAttribute(jdicspan, "font-size", "10pt");

  jdicdiv.appendChild( jdicspan );
  jdicdiv.appendChild( document.createElement("br") );

  list = card["kanji"];

  for ( j = 0 ; j < card["subcard"].length ; j++ )
    list = list + card["subcard"][j]["kanji"];

  if ( appendRefLinks(jdicdiv, getKanjis(list)) )
    return jdicdiv;
  else
    return null;
}

function appendRefLinks(div, string) {
  var empty, i, character, child;

  empty = true;
  for ( i = 0 ; i < string.length ; i++ ) {
    if ( contents["backreference"][string.charAt(i)].length > 1 ) {
      character = string.charAt(i);

      if ( !empty )
        div.appendChild(document.createTextNode(" - "));
      else
        empty = false;

      child = document.createElement("span");

      child.appendChild(document.createTextNode(character));

      setAttribute(child, "onClick", "javascript:openRef(\"" + character + "\")");
      //setAttribute(child, "onClick", "javascript:alert(this.parentNode.parentNode.getAttribute('id'))");
      setAttribute(child, "class", "link");

      div.appendChild(child);
    }
  }

  return !empty;
}

function getReportSubject(k, u) {
  var K = (k + 1) + '';
  var U = u + '';
  var unit;

  while ( U.length < 2 )
    U = '0' + U;

  while ( K.length < 3 )
    K = '0' + K;

  for ( unit = 0 ; unit < contents["unit"].length ; unit++ )
    if ( contents["unit"][unit]["id"] == u )
      break;

//  return "Segnalazione sulla lezione " + U + ", scheda " + K + " (" + contents["unit"][unit]["card"][k]["kanji"] + ")";
  return "Segnalazione sulla lezione " + U + ", scheda " + K;
}

function createCardDoubt(k, u) {
  var a;

  a = createEMailAnchorSubject("Se hai le informazioni mancanti in questa scheda inviamele per favore", "yomukanji", "lightless.org", getReportSubject(k, u));
  setAttribute(a, "class", "doubt");

  return a;
}

function createCardReport(k, u) {
  var a;

  a = createEMailAnchorSubject("Invia una segnalazione su questa scheda", "yomukanji", "lightless.org", getReportSubject(k, u));
  setAttribute(a, "class", "report");

  return a;
}

/* ---------- */

function openRef(character) {
  var ext, doc;

  if ( isIE() ) {
    // We have to close the window before writing in it. Thanks again IE!
    ext = window.open("", "external", "", "replace");
  } else {
    ext = window.open("", "external");
  }

  doc = ext.document;

  doc.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n');
  doc.write('<html><head><title>Yomukanji - ' + character + '</title>');
  doc.write('<script type="text/javascript">' + lightOn + lightOff + setAttribute + hasClass + isIE + '</script>');

  doc.write('<style type="text/css">body {text-align: center;} .main {text-align: center; border: solid 2px; background-color: #EEEEFF; border-color: #4444CC; color: #000088; padding: 1mm; margin: 5mm;} .title {font-size: 20pt;} .subcard {border-color: inherit; border: dashed 1px; margin: 2mm;} .mainOn {color: #4040E8;} .mainOnUnderline {color: #4040E8; text-decoration: underline;} @media print {.main {background-color: transparent; border-color: #000000; color: #000000; page-break-inside: avoid;}}</style></head>');
  doc.write('<body onload="window.opener.populateRef(\'' + character + '\', document, false); window.focus()"></body></html>');

  doc.close();
}

function populateRef(character, doc, breakBefore) {
  var bo, mks, C, lastUnit, sc, kaku, div, card, r;

  bo = doc.getElementsByTagName('body')[0];

  mks = doc.createElement("span");
  setAttribute(mks, "font-size", "60pt");
  if ( breakBefore )
    setAttribute(mks, 'class', 'breakBefore');
  mks.appendChild( doc.createTextNode(character) );

  bo.appendChild( mks );
  bo.appendChild( doc.createElement('br') );
  if ( isPicture('soder') ) {
    var img = doc.createElement("img");
    setAttribute(img, 'src', getStrokesLink(character, 'soder'));
    bo.appendChild(img);
  }

  bo.appendChild( doc.createElement('br') );

  C = contents["backreference"][character];

  lastUnit = null;
  for ( sc = 0 ; sc < C.length ; sc++ ) {
    if ( C[sc]["unit"] != lastUnit ) {
      bo.appendChild( createTitle(contents["unit"][C[sc]["unit"]]["title"], doc) );

      if ( C[sc]["unit"] == getKakuUnit(character) ) {
        bo.appendChild( doc.createElement('br') );

        kaku = doc.createElement("span");
        setAttribute(kaku, "font-size", "10pt");
        kaku.appendChild( doc.createTextNode(contents["kaku"]) );

        bo.appendChild( kaku );
      }

      div = doc.createElement("div");
      setAttribute(div, "class", "main");

      bo.appendChild( div );

      lastUnit = C[sc]["unit"];
    }

    card = contents["unit"][C[sc]["unit"]]["card"][C[sc]["card"]];
    if ( typeof(C[sc]["subcard"]) != 'undefined' )
      card = card["subcard"][C[sc]["subcard"]];

    div.appendChild( createSubcard(card, doc, sc + 1, 0, 0) );
  }

  r = createRadicalSubcard( character, false, doc );
  if ( r != null ) {
    bo.appendChild( createTitle("Radicali", doc) );

    div = doc.createElement("div");
    setAttribute(div, "class", "main");

    div.appendChild( r );
    bo.appendChild( div );
  }
}

function getKakuUnit(character) {
  var C, i;

  C = contents["backreference"][character];

  for ( i = 0 ; i < C.length ; i++ )
    if ( typeof(C[i]["subcard"]) == 'undefined' &&
         contents["unit"][C[i]["unit"]]["card"][C[i]["card"]]["kaku"] )
      return C[i]["unit"];

  return null;
}

/* ---------- */

function initUnit(n) {
  var body, tsp, csp, d, i, j, tmp;

  cleanPage();

  unit = contents["unit"][n];

  body = document.getElementsByTagName("body")[0];
  body.appendChild( createHeader() );
  body.appendChild( createFooter() );

  tsp = document.createElement("span");
  setAttribute(tsp, "font-size", "20pt");
  tsp.appendChild( document.createTextNode(unit["title"]) )

  csp = document.createElement("span");
  setAttribute(csp, "id", "counter");

  d = document.createElement("div");
  d.appendChild( tsp );
  d.appendChild( document.createElement("br") );
  d.appendChild( csp );
  
  body.insertBefore(d, document.getElementById("footer"));

  results = new Array();

  pi = new Array();
  
  for ( i = 0 ; i < unit["card"].length ; i++ ) {
    pi[i] = i;
  }

  for ( i = 0 ; i < pi.length ; i++ ) {
    j = Math.floor( Math.random() * (pi.length - i) ) + i;
    tmp = pi[i];
    pi[i] = pi[j];
    pi[j] = tmp;
  }

  displayTest(unit, pi, 0, results);
}

function displayTest(unit, pi, k, results) {
  var div, body, counter;

  div = document.createElement("div");
  setAttribute(div, "id", "test-" + unit['id'] + "-" + k);
  setAttribute(div, "class", "main");

  div.appendChild( createTitle("Come si Legge e Cosa Significa?", document) );
  div.appendChild( document.createElement("br") );

  div.appendChild( createFalseLink("Visualizza Soluzione", "displaySolution(unit, pi, " + k + ", results)") );
  div.appendChild( document.createElement("br") );

  div.appendChild( createMegaKanjiSpan(unit["card"][pi[k]]["kanji"], document, unit["id"], pi[k], null) );

  body = document.getElementsByTagName("body")[0];
  body.insertBefore(div, document.getElementById('headert').nextSibling.nextSibling);

  counter = document.getElementById("counter");
  removeChildren(counter);
  counter.appendChild( document.createTextNode((k + 1) + "/" + pi.length) );
}

function attachKernel(div, unit, pik) {
  var card, meaning, count, sc, i, r, ref, strokes;

  card = unit["card"][pik];

  div.appendChild( createMegaKanjiSpan(card["kanji"], document, unit['id'], pik, null) );
  div.appendChild( document.createElement("br") );

  meaning = card["meaning"];
  for ( count = 0 ; count < card["meaning"].length ; count++ ) {
    div.appendChild( createMeaningSpan( card["meaning"][count], document, unit['id'], pik, null, count) );
    div.appendChild( document.createElement("br") );
  }

  for ( sc = 0 ; sc < card["subcard"].length ; sc++ )
    div.appendChild( createSubcard( card["subcard"][sc], document, unit['id'], pik, sc) );

  for ( i = 0 ; i < card["radicals"].length ; i++ ) {
    r = createRadicalSubcard( card["radicals"].charAt(i), true, document );
    if ( r != null )
      div.appendChild( r );
  }

  if ( card["kaku"] || card["note"] != "" )
    div.appendChild( createNote(card) );

  ref = createRef(card);
  if ( ref != null )
    div.appendChild( createRef(card) );

  strokes = createWwwjdic(card);
  if ( strokes != null )
    div.appendChild( createWwwjdic(card) );
}

function displaySolution(unit, pi, k, results) {
  var card, div;

  card = unit["card"][pi[k]];
  div = document.getElementById("test-" + unit['id'] + "-" + k);
  removeChildren( div );

  div.appendChild( createTitle("La tua Risposta è Giusta?", document) );
  div.appendChild( document.createElement("br") );

  div.appendChild( createFalseLink("Risposta Giusta", "answer(unit, pi, " + k + ", results, true)") );
  div.appendChild( document.createTextNode(" - ") );
  div.appendChild( createFalseLink("Risposta Sbagliata", "answer(unit, pi, " + k + ", results, false)") );
  div.appendChild( document.createElement("br") );

  attachKernel(div, unit, pi[k]);

  if ( !card["doubt"] )
    div.appendChild( createCardReport(pi[k], unit['id']) );
  else 
    div.appendChild( createCardDoubt(pi[k], unit['id']) );
}

function answer(unit, pi, k, results, isRight) {
  var card, div;

  card = unit["card"][pi[k]];
  div = document.getElementById("test-" + unit['id'] + "-" + k);
  removeChildren( div );

  setAttribute(div, "class", isRight? "right" : "wrong");

  div.appendChild( createTitle(isRight ? "Risposta Giusta" : "Risposta Sbagliata", document) );
  div.appendChild( document.createElement("br") );

  attachKernel(div, unit, pi[k]);

  if ( !card["doubt"] )
    div.appendChild( createCardReport(pi[k], unit['id']) );
  else 
    div.appendChild( createCardDoubt(pi[k], unit['id']) );

  results[k] = isRight;

  if ( k + 1 < pi.length )
    displayTest(unit, pi, k + 1, results);
  else
    displayResults(unit, pi, results);  
}

function displayResults(unit, pi, results) {
  var ok, ko, i, div, a, text, body;

  ok = 0;
  ko = 0;
  for ( i = 0 ; i < results.length ; i++ )
    if ( results[i] )
      ok++;
    else
      ko++;

  div = document.createElement("div");
  setAttribute(div, "id", "results");
  setAttribute(div, "class", "main");

  a = document.createElement("span");
  setAttribute(a, "font-size", "20pt");
  text = document.createTextNode("Risultato");
  a.appendChild(text);

  div.appendChild( a );
  div.appendChild( document.createElement("br") );

  a = document.createElement("span");
  setAttribute(a, "font-size", "25pt");
  text = document.createTextNode(Math.round(100.0 * ok / (ok + ko)) + "%");
  a.appendChild(text);

  div.appendChild( a );
  div.appendChild( document.createElement("br") );

  a = document.createElement("span");
  text = document.createTextNode("Risposte Giuste: " + ok);
  a.appendChild(text);

  div.appendChild( a );
  div.appendChild( document.createElement("br") );

  a = document.createElement("span");
  text = document.createTextNode("Risposte Sbagliate: " + ko);
  a.appendChild(text);
  
  div.appendChild( a );
  div.appendChild( document.createElement("br") );
  div.appendChild( document.createElement("br") );

  a = document.createElement("span");
  setAttribute(a, "class", "hov");
  setAttribute(a, "onClick", "chooseUnit()");

  text = document.createTextNode("Torna al Menù");
  a.appendChild(text);

  div.appendChild( a );

  body = document.getElementsByTagName("body")[0];
  body.insertBefore(div, document.getElementById('headert').nextSibling.nextSibling);
}

/* ---------- */

function getOptions(url) {
  var opt = new Array();

  var a = url.split('?');

  if ( a.length > 1 ) {
    var o = a[ a.length - 1 ];

    var l = o.split(';');

    for ( var i = 0 ; i < l.length ; i++ ) {
      var e = l[i].split('=');

      if ( e.length == 2 )
        opt[ decodeURIComponent(e[0]) ] = decodeURIComponent(e[1]);
    }
  }

  if ( typeof( opt["dic"] ) == "undefined" )
    opt["dic"] = "default";

  if ( typeof( opt["kanji"] ) != "undefined" )
    opt["kanji"] = String.fromCharCode( opt["kanji"] );

  return opt;
}

function init() {
  var y, c, n, i, unitList, img;

  if ( typeof( options['mode'] ) == 'undefined' ) {
    chooseUnit();
  } else if ( options['mode'] == 'review' ) {
    createFrameSet();
  } else if ( options['mode'] == 'listunits' ) {
    var body = document.getElementsByTagName("body")[0];
 
    var yomuDivList = getYomuDivList();
    var kakuDivList = getKakuDivList();

    printKanjiList(yomuDivList, kakuDivList);

    if ( isPicture('wwwjdic') ) {
      img = document.createElement("img");
      setAttribute(img, "id", "kakuframe");
      setAttribute(img, "onClick", "reloadImg()");
      document.getElementsByTagName("body")[0].appendChild( img );
    }
  } else if ( options['mode'] == 'kanji' ) {
    populateRef(options['kanji'], document, false);
  }
}

function createFrameSet() {
  var html, body, frameset, left, right;

  html = document.getElementsByTagName('html')[0];
  body = document.getElementsByTagName('body')[0];

  html.removeChild(body);

  frameset = document.createElement("frameset");
  //setAttribute(frameset, 'cols', '400,*');
  setAttribute(frameset, 'cols', '*,*');
  
  left = document.createElement('frame');
  setAttribute(left, 'src', '?mode=listunits;dic=' + options['dic']);
  setAttribute(left, 'name', 'leftFrame');

  right = document.createElement('frame');
//  setAttribute(right, 'id', 'rightFrame');
  setAttribute(right, 'src', 'about:blank');
  setAttribute(right, 'name', 'rightFrame');
  
  frameset.appendChild(left);
  frameset.appendChild(right);

  html.appendChild(frameset);
}

function chooseUnit() {
  var body, div, a, text, i, span, br;

  cleanPage();

  body = document.getElementsByTagName("body")[0];
  body.appendChild( createHeader() );

  div = document.createElement("div");
  setAttribute(div, "class", "main");

  a = document.createElement("span");
  setAttribute(a, "font-size", "20pt");
  text = document.createTextNode("Seleziona Unità per il Test");
  a.appendChild(text);

  div.appendChild( a );
  div.appendChild( document.createElement("br") );

  for ( i = 0 ; i < contents["unit"].length ; i++ ) {
    span = document.createElement("span");
    setAttribute(span, "class", "hov");
    setAttribute(span, "onClick", 'initUnit(' + i + ')');

    text = document.createTextNode(contents["unit"][i]["title"]);

    span.appendChild( text );
    div.appendChild( span );

    br = document.createElement("br");

    div.appendChild( br );
  }

  body.appendChild( div );

  body.appendChild( createFooter() );
}

function printKanjiList(yomuDivList, kakuDivList) {
  var bo = document.getElementsByTagName('body')[0];

  var banner = document.createElement("span");
  setAttribute(banner, "font-size", "30pt");
  banner.appendChild( document.createTextNode(contents["atarashii"]) );

  bo.appendChild( banner );
  bo.appendChild( document.createElement("br") );

  for ( var i = 0 ; i < contents["unit"].length ; i++ ) {
    var div;

    bo.appendChild( createTitle(contents["unit"][i]["title"], document) );
//    bo.appendChild( document.createElement("br") );
//    bo.appendChild( document.createTextNode( contents["yomu"] + " (" + yomuDivList[i].length + ")" ) );

    div = document.createElement("div");
    setAttribute(div, "class", "main");
    
    for ( var j = 0 ; j < yomuDivList[i].length ; j++ ) {
      div.appendChild( yomuDivList[i][j] );
      div.appendChild( document.createTextNode(" ") );
    }

    bo.appendChild(div);
//  bo.appendChild( document.createTextNode( contents["kaku"] + " (" + kakuDivList[i].length + ")" ) );
    div = document.createElement("div");
    setAttribute(div, "class", "main");
    
    for ( var j = 0 ; j < kakuDivList[i].length ; j++ ) {
      div.appendChild( kakuDivList[i][j] );
      div.appendChild( document.createTextNode(" ") );
    }

    bo.appendChild(div);
  }

  var yomuSum = 0, kakuSum = 0;
  var table, tr, td;
  table = document.createElement("table");
  setAttribute(table, "style", "width: 100%");
  tr = document.createElement("tr");
  td = document.createElement("td");
  tr.appendChild(td);
  td = document.createElement("td");
  td.appendChild( document.createTextNode( contents["yomu"] ) );
  tr.appendChild(td);
  td = document.createElement("td");
  td.appendChild( document.createTextNode( contents["kaku"] ) );
  tr.appendChild(td);
  table.appendChild(tr);
  
  for ( var i = 0 ; i < contents["unit"].length ; i++ ) {
    tr = document.createElement("tr");
    td = document.createElement("td");
    td.appendChild( document.createTextNode( contents["unit"][i]["title"] ) );
    tr.appendChild(td);
    td = document.createElement("td");
    td.appendChild( document.createTextNode( yomuDivList[i].length ) );
    tr.appendChild(td);
    td = document.createElement("td");
    td.appendChild( document.createTextNode( kakuDivList[i].length ) );
    tr.appendChild(td);
    table.appendChild(tr);

    yomuSum += yomuDivList[i].length;
    kakuSum += kakuDivList[i].length;
  }

  tr = document.createElement("tr");
  td = document.createElement("td");
  td.appendChild( document.createTextNode( "Totale" ) );
  tr.appendChild(td);
  td = document.createElement("td");
  td.appendChild( document.createTextNode( yomuSum ) );
  tr.appendChild(td);
  td = document.createElement("td");
  td.appendChild( document.createTextNode( kakuSum ) );
  tr.appendChild(td);
  table.appendChild(tr);

  bo.appendChild( document.createElement("hr") );

  var div = document.createElement("div");
  div.appendChild(table);
  setAttribute(div, "class", "main");
  bo.appendChild(div);
}

function getYomuDivList() {
  var yomuDivList, unitList, div, i, j, a, url, character;

  yomuDivList = new Array();

  unitList = getKanjiList(false);

  for ( i = 0 ; i < contents["unit"].length ; i++ ) {
    yomuDivList[i] = new Array();

    for ( j = 0 ; j < unitList[i].length ; j++ ) {
      character = unitList[i].charAt(j);

      a = document.createElement('a');
      a.appendChild( document.createTextNode( character ) );
      setAttribute(a, "font-size", "20pt");

      if ( isPicture('wwwjdic') )
	setAttribute(a, "onClick", "setImg('" + character + "')");

      url = "?mode=kanji;kanji=" + character.charCodeAt(0) + ';dic=' + options['dic'];

      setAttribute(a, "href", url);
      setAttribute(a, "target", "rightFrame");

      yomuDivList[i][ yomuDivList[i].length ] = a;

    }
  }

  return yomuDivList;
}

function getKakuDivList() {
  var kakuDivList, list, div, i, j, a, url, character;

  kakuDivList = new Array();

  list = getKanjiList(true);

  for ( i = 0 ; i < contents["unit"].length ; i++ ) {
    kakuDivList[i] = new Array();

    for ( j = 0 ; j < list.length ; j++ ) {
      character = list.charAt(j);

      if ( getKakuUnit( character ) == i ) {
        a = document.createElement('a');
        a.appendChild( document.createTextNode( character ) );
        setAttribute(a, "font-size", "20pt");

        if ( isPicture('wwwjdic') ) {
	  setAttribute(a, "onClick", "setImg('" + character + "')");
          url = "?mode=kanji;kanji=" + character.charCodeAt(0) + ';dic=' + options['dic'];
        } else {
          url = getStrokesLink(character, 'wwwjdic');
        }

        setAttribute(a, "href", url);
        setAttribute(a, "target", "rightFrame");

        kakuDivList[i][ kakuDivList[i].length ] = a;
      }
    }
  }

  return kakuDivList;
}

function reloadImg() {
  var img, src;

  if ( isPicture('wwwjdic') ) {
    img = document.getElementById('kakuframe');
    src = img.getAttribute('src');

    setAttribute(img, "src", "");
    setAttribute(img, "src", src);
  }
}

function setImg(character) {
  if ( isPicture('wwwjdic') )
    setAttribute(document.getElementById('kakuframe'), 'src', getStrokesLink(character, 'wwwjdic'));
}

function getKanjiList(unique) {
  var A, list, i, j, s, l, c;

  A = new Array();
  list = '';

  for ( i = 0 ; i < contents["unit"].length ; i++ ) {
    A[i] = '';

    for ( j = 0 ; j < contents["unit"][i]["card"].length ; j++ ) {
      s = contents["unit"][i]["card"][j]["kanji"];
      for ( l = 0 ; l < s.length ; l++ )
        if ( isKanji(s, l) ) {
          c = s.charAt(l);
          if ( list.indexOf(c) == -1 ) {
            A[i] += c;
            list += c;
          }
        }
    }
  }

  if ( unique )
    return list;
  else
    return A;
}

var unit, display, pi, results;

contents["backreference"] = getBackReference();

options = getOptions( document.location.href );
