// Copyright 2007 Ray L. Morton-Ewbank. All Rights Reserved

function wcg_isAlpha(c) {
  return wcg_isLower(c) || wcg_isUpper(c);
}

function wcg_isUpper(c) {
  if (wcg_uc.indexOf(c) >= 0) {
     return 1;
  }
  return 0;
}
function wcg_isLower(c) {
  if (wcg_lc.indexOf(c) >= 0) {
     return 1;
  }
  return 0;
}

function wcg_map(c,toc) {
  wcg_umap[c] = toc;
  wcg_uimap[toc] = c;  
}

function wcg_unmap_c(c) {
  var toc = wcg_umap[c];
  if (toc) {
    delete wcg_uimap[toc];  
    delete wcg_umap[c];
  }
}

function wcg_unmap_toc(toc) {
  var c = wcg_uimap[toc];
  if (c) {
    delete wcg_uimap[toc];  
    delete wcg_umap[c];
  }
}
function wcg_getOptionsHtml() {
  s =""
  if (!wcg_showing_help) {
    s += " &nbsp;<a href='javascript:wcg_setShowHelp()'>Show Help</a>";
  }
  else {
    s += " &nbsp;<a href='javascript:wcg_setHideHelp()'>Hide Help</a>";
  }
  if (!wcg_showing_attribution) {
    s += " &nbsp;<a href='javascript:wcg_setShowAttribution()'>Show Attribution</a>";
  }
  else {
    s += " &nbsp;<a href='javascript:wcg_setHideAttribution()'>Hide Attribution</a>";
  }
  if (!wcg_showing_errors) {
    s += " &nbsp;<a href='javascript:wcg_setShowErrors()'>Show Errors</a>";
  }
  else {
    s += " &nbsp;<a href='javascript:wcg_setHideErrors()'>Hide Errors</a>";
  }
  if (!wcg_showing_letter_counts) {
    s += " &nbsp;<a href='javascript:wcg_setShowLetterCounts()'>Show Letter Counts</a>";
  }
  else {
    s += " &nbsp;<a href='javascript:wcg_setHideLetterCounts()'>Hide Letter Counts</a>";
  }
  s += " &nbsp;<a href='javascript:wcg_showMe()'>Show Me</a>";
  s += " &nbsp;<a href='javascript:wcg_hitMe()'>Hit Me</a>";
  return s;
}

function wcg_setShowHelp() {
  wcg_showme = 0;
  wcg_showing_help = 1;
  wcg_refresh();
}
function wcg_setHideHelp() {
  wcg_showme = 0;
  wcg_showing_help = 0;
  wcg_refresh();
}
function wcg_setShowAttribution() {
  wcg_showme = 0;
  wcg_showing_attribution = 1;
  wcg_refresh();
}
function wcg_setHideAttribution() {
  wcg_showme = 0;
  wcg_showing_attribution = 0;
  wcg_refresh();
}
function wcg_setShowErrors() {
  wcg_showme = 0;
  wcg_showing_errors = 1;
  wcg_refresh();
}
function wcg_setHideErrors() {
  wcg_showme = 0;
  wcg_showing_errors = 0;
  wcg_refresh();
}
function wcg_setShowLetterCounts() {
  wcg_showme = 0;
  wcg_showing_letter_counts = 1;
  wcg_refresh();
}
function wcg_setHideLetterCounts() {
  wcg_showme = 0;
  wcg_showing_letter_counts = 0;
  wcg_refresh();
}

function wcg_getHelpHtml() {
  var s = "<hr/><br/>"
  s+= '<h3>Help</h3>Click <b>"Hit Me"</b> a few times.  Each time you will ';
  s+= 'be shown a new letter at random.<br/>Click <b>"Show Me"</b> to ';
  s+= 'to choose a particular letter to be shown (you will be prompted)<br/>';
  s+= 'Click <b>any letter</b> to substitute it (you will be prompted)<br/>'; 
  s+= 'Click <b>substituted letter</b> to un-substitute it<br/>'; 
  s+= '<b>"Show/Hide Help"</b> shows or hides this help message<br/>'; 
  s+= '<b>"Show/Hide Attribution"</b> shows or hides the attribution<br/>'; 
  s+= '<b>"Show/Hide Errors"</b> show errors in curly braces (or not)<br/>'; 
  s+= '<b>"Show/Hide Letter Counts"</b> show/hide letter counts<br/> ';
  return s
}
function wcg_getQuoteHtml() {
  var i;
  var bcnt = 0;
  var dcnt = 0;
  var s = "<hr/>";
  if (wcg_showme) {
    s += "<b>Show what? </b><br/>";
  }
  var c_unmapped = 0;
  var c_wrong = 0;
  for (i=0; i<wcg_qlen; i++) {
    var c = wcg_quote.charAt(i);
    if (c == '<') {
      bcnt++;
      s += c;
    }
    else if ((bcnt > 0) && (c == '>')) {
      bcnt--;
      s += c;
    }
    else if (c == '&') {
      dcnt++;
      s += c;
    }
    else if ((dcnt > 0) && (c == ';')){
      dcnt--;
      s += c;
    }
    else if ((bcnt == 0) && (dcnt == 0)) {
      if (c == ' ') {
        s += " &nbsp; ";
      }
      else if (wcg_isAlpha(c)) {
         var uc = wcg_isUpper(c);
         var cl = c.toLowerCase();
         var cm = wcg_cmap[cl];
         var cmu = wcg_umap[cm];
         if (cmu) {
           cm = cmu;
         }
         var cmc = cm;
         if (uc) {
           cmc = cm.toUpperCase();
         }
         if (cmu) {
           var cw = 0;
           if (cl != cmu) {
//             alert("" + cw + " " + cmu);
             c_wrong++;
             cw = 1;
           }
           if (cw && wcg_showing_errors) {
             s += '<a class="wcg_mapped" href=\'javascript:wcg_doUnMap("' + cm + 
                 '")\'>{' + cmc + '}</a>';
           }
           else {
             s += '<a class="wcg_mapped" href=\'javascript:wcg_doUnMap("' + cm + 
                 '")\'>' + cmc + '</a>';
           }
         }
         else {
           c_unmapped++;
           s += '<a class="wcg_unmapped" href=\'javascript:wcg_doMap("' + cm + '")\'>' + cmc + '</a>';
         }
      }
      else {
        s += c;
      }
    }
    else {
      s += c;
    }
  }
  wcg_done = 0;
  if ((c_unmapped == 0) && (c_wrong == 0)) {
    wcg_done = 1;
    s += "<br><h2>CONGRATULATIONS ON SOLVING THE PUZZLE CORRECTLY!</h2>";
  }
  else if (c_unmapped == 0) {
    s += "<br><h2>SORRY, YOUR FINAL ANSWER IS INCORRECT</h2>";
  }
  return s;
}

function wcg_getMappingCharHtml() {
  var n = wcg_lc.length;
  var i;
  var s = '<hr/><b>Replace \'' + wcg_mappinwcg_char + '\' with: </b>';
  for (i=0; i<n; i++) {
     var c = wcg_lc.charAt(i);
     if (!wcg_uimap[c]) {
       s += '&nbsp; <a href=\'javascript:wcg_mapTo("' + c + '")\'><i>' + c + '</i></a>';
     }
  }
  return s;
}
function wcg_mapTo(c) {
  wcg_showme = 0;
  wcg_map(wcg_mappinwcg_char,c);
  wcg_mappinwcg_char = null;
  wcg_refresh();
}

function wcg_doMap(c) {
  if (wcg_showme) {
    var ci = wcg_getCi(c);
    wcg_map(c,ci);
    wcg_showme = 0;
  }
  else {
    wcg_mappinwcg_char = c; 
  }
  wcg_refresh();
}

function wcg_doUnMap(c) {
  if (wcg_showme) {
    wcg_showme = 0;
  }
  else {
    wcg_unmap_toc(c);
  }
  wcg_refresh();
}

function wcg_getCi(c) {
  var ci;
  for (ci in wcg_cmap) {
    if (wcg_cmap[ci] == c) {
      break;
    }
  }
  return ci;
}

function wcg_showLetter(c) {
  wcg_showme = 0;
  var ci = wcg_getCi(c);
  wcg_map(c,ci);
  wcg_refresh();
}


function wcg_showMe() {
  wcg_mappinwcg_char = null;
  wcg_showme = 1;
  wcg_refresh();
}

function wcg_hitMe() {
  wcg_showme = 0;
  if (wcg_letterCounts == null) {
    wcg_letterCounts = wcg_getLetterCounts();
  }
  var k;
  var ca = [];
  for (c in wcg_letterCounts) {
    var cm = wcg_cmap[c];
    if (!wcg_umap[cm]) {
      ca.push(cm);
    }
  }
  // ca is now list of cipher letters not mapped
  var calen = ca.length;
  while (calen > 0) {
    k = Math.floor(Math.random()*calen);
    if (k > calen - 1) {
      k = calen - 1;
    }
    var cm = ca[k];
    var ci = wcg_getCi(cm);
    if (wcg_uimap[ci]) {
      delete ca[k];
      calen = ca.length;
    }
    else {
      break;
    }
  }
  wcg_showLetter(cm);
}

function wcg_getIdentityMap() {
  var map = {}
  var n = wcg_lc.length;
  var i;
  for (i=0; i<n; i++) {
    var c = wcg_lc.charAt(i);
    map[c] = c;
  }
  return map;
}

function wcg_getRandomMap() {
  var map = {}
  var n = wcg_lc.length;
  var ca = wcg_lc.split("");
  var i;
  for (i=0; i<n; i++) {
    var c = wcg_lc.charAt(i);
    var k = Math.floor(Math.random()*(n-i));
    if (k > n-i-1) {
       k = n-i-1;
    }
    map[c] = ca[k];
    ca[k] = ca[n-i-1];
  }
  return map;
}
function wcg_getLetterCounts() {
  var cm = {};
  var i;
  for (i=0; i<wcg_qlen; i++) {
    var c = wcg_quote.charAt(i);
    if (wcg_isAlpha(c)) {
      cl = c.toLowerCase();
      if (!cm[cl]) {
        cm[cl] = 1;
      }
      else {
        cm[cl]++;
      }
    }
  }
  return cm;
}

function wcg_lcSortBy(a,b) {
  return wcg_letterCounts[b] - wcg_letterCounts[a];
}
function wcg_getLetterCountsHtml() {
  if (wcg_letterCounts == null) {
    wcg_letterCounts = wcg_getLetterCounts();
  }
  var ca = new Array();
  var k;
  for (k in wcg_letterCounts) {
    ca.push(k);
  }
  ca.sort(wcg_lcSortBy);
//  alert(ca.join());
  var cal = [];
  var calen = ca.length;
  var i;
  var s = "<hr/><b>Letter Counts: </b>";
  for (i=0; i<calen; i++) {
    var c = ca[i];
    var cm = wcg_cmap[c];
    if (!wcg_umap[cm]) {
      s += '&nbsp; <a class="wcg_unmapped" href=\'javascript:wcg_doMap("' + cm + '")\'>' + cm  + '</a>' + "=" + wcg_letterCounts[c];
    }
  }
  return s;
}

function wcg_refresh() {
  var s = '<b>Bible Cryptogram</b><br/><br/>';
  s += wcg_getOptionsHtml();
  if (wcg_mappinwcg_char && !wcg_done) {
    s += wcg_getMappingCharHtml();
  }
  s += wcg_getQuoteHtml();
  if (wcg_showing_letter_counts && !wcg_done) {
    s += wcg_getLetterCountsHtml();
  }
  if (wcg_showing_attribution || wcg_done) {
    s += "<hr/><b> Attribution: </b>" + wcg_attribution;
  }
  if (wcg_showing_help) {
    s += wcg_getHelpHtml();
  }
  var el = document.getElementById("wcg_target");
  el.innerHTML = s;
}

wcg_s = "Full fathom five thy father lies;<br/>";
wcg_s += "Of his bones are coral made;<br/>";
wcg_s += "Those are pearls that were his eyes:<br/>";
wcg_s += "Nothing of him that doth fade<br/>";
wcg_s += "But doth suffer a sea-change<br/>";
wcg_s += "Into something rich and strange.<br/>";
wcg_s += "Sea-nymphs hourly ring his knell<br/>";
wcg_s += "Hark! now I hear them,--Ding-dong, bell.<br/>";

wcg_quote = wcg_s;
wcg_qlen = wcg_quote.length;

wcg_s = 'William Shakespeare (1564-1616), British dramatist, poet. Ariel in The Tempest, Act 1, Sc. 2'
wcg_attribution = wcg_s;

wcg_showing_help = 0;
wcg_done = 0;
wcg_showing_attribution = 1;
wcg_showing_errors = 1;
wcg_showing_letter_counts = 0;
wcg_letterCounts = null;
wcg_mappinwcg_char = null;
wcg_showme = 0;
wcg_lc="abcdefghijklmnopqrstuvwxyz";
wcg_uc="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
wcg_cmap= wcg_getRandomMap()
wcg_umap = {};
wcg_uimap = {};

wcg_quote=wcg_q
wcg_qlen = wcg_quote.length;

wcg_attribution=wcg_a
