// This program uses the Prototype Javascript Library (version 1.6.0.2), LowPro Javascript Library (version 0.5), and Firebug.
// Written by Sean Bouchard, September 2008.
// Public domain. No guarantees implied. Use at your own risk.

var alphabet = "abcdefghijklmnopqrstuvwxyz";
var simpleEncoding = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

var chartFormat = new Array();
chartFormat['colors'] = "&amp;chco=ff0000,ffbb66,aa6622,00bbbb";
chartFormat['labels'] = "";
chartFormat['title'] = "";
chartFormat['spacing'] = "&amp;chbh=10,0,4";

var count = 0;
 
function simpleEncode(valueArray,maxValue) 
{
   var chartData = ['s:'];
   for (var i = 0; i < valueArray.length; i++) 
   {
      var currentValue = valueArray[i];
      if (!isNaN(currentValue) && currentValue >= 0) 
      {
         chartData.push(simpleEncoding.charAt(Math.round((simpleEncoding.length-1) * currentValue / maxValue)));
      }
      else 
      {
         chartData.push('_');
      }
   }
   return chartData.join('');
}

function simpleEncodeMultiple(multipleValueArray,maxValue)
{
   var chartData = ['s:'];
   for (var i = 0; i < multipleValueArray.length; ++i)
   {
      if (i != 0) chartData.push(',');
      for (var j = 0; j < 26; ++j)
      {
         var currentValue = multipleValueArray[i][j];
         if (!isNaN(currentValue) && currentValue >= 0) 
         {
            chartData.push(simpleEncoding.charAt(Math.round((simpleEncoding.length-1) * currentValue / maxValue)));
         }
         else 
         {
            chartData.push('_');
         }
      }
   }
   return chartData.join('');
}

function splitTextIntoUniqueWords(text)
{
   var words = text.toLowerCase().gsub(/[^a-z0-9]/, " ").split(/\s/);
   words.each(function(w) { w.replace(/^\s+|\s+$/g, ''); });
   words.sort();
   
   // for (var i = 0; i < words.length; ++i)
   // {
      // console.log(words[i]);
   // }
         
   var uniqueWords = new Array();
   var prevWord = "";
   
   for (var i = 0; i < words.length; ++i)
   {
      if (!words[i].match(/[0-9]/))
      {
         var strictlyAlphaWord = words[i].gsub(/[^a-z]/, "");
         
         if (strictlyAlphaWord != prevWord && strictlyAlphaWord.length >= 3)
         {
            uniqueWords.push(strictlyAlphaWord);
            prevWord = strictlyAlphaWord;
         }
      }
   }
   
   // for (var i = 0; i < uniqueWords.length; ++i)
   // {
      // console.log(uniqueWords[i]);
   // }
   
   return uniqueWords;
}

function splitTextIntoWords(text)
{
   var words = text.toLowerCase().gsub(/[^a-z0-9]/, " ").split(/\s/);
   words.each(function(w) { w.replace(/^\s+|\s+$/g, ''); });
   words.sort();
   
   var validWords = new Array();
   
   for (var i = 0; i < words.length; ++i)
   {
      if (!words[i].match(/[0-9]/))
      {
         var strictlyAlphaWord = words[i].gsub(/[^a-z]/, "");
         
         if (strictlyAlphaWord.length >= 3)
         {
            validWords.push(strictlyAlphaWord);
         }
      }
   }
   
   return validWords;
}

function countLettersInWords(words)
{         
   var letters = new Array();
   for (var i = 0; i < 26; ++i)
   {
      letters[i] = 0;
   }

   for (var i = 0; i < words.length; ++i)
   {
      for (var j = 0; j < words[i].length; ++j)
      {
         //console.log("words[" + i + "]: " + words[i] + "; j: " + j);
         var letter = alphabet.search(words[i].charAt(j));
         ++letters[letter];
         ++count;
      }
   }
   
   return letters;
}

function calculateFrequencies(letters)
{
   var frequencies = new Array();

   for (var i = 0; i < 26; ++i)
   {
      frequencies[i] = Math.round((letters[i] / count) * 100) / 100.0;
   }
   
   // for (var i = 0; i < 26; ++i)
   // {
      // console.log("freq[" + i + "]: " + frequencies[i]);
   // }
   
   return frequencies;
}

function getMaxValueFromLetters(letters)
{
   var max = 0;
   
   for (var i = 0; i < letters.length; ++i)
   {
      if (letters[i] > max)
      {
         max = letters[i];
      }
   }
   
   return max;
}

function labelsInSortOrder(sortOrder)
{
   var labels = ('a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z').split('|');
   return putIntoSortOrder(labels, sortOrder).join('|');
}

function calculateMaxValueFromMultipleArrays(multipleValueArray)
{
   var high = 0;
   for (var i = 0; i < multipleValueArray.length; ++i)
   {
      for (var j = 0; j < multipleValueArray[i].length; ++j)
      {
         if (multipleValueArray[i][j] > high)
         {
            high = multipleValueArray[i][j];
         }
      }
   }
   return high;
}

function outputAnalysis(multipleValueArray, sortOrder)
{
   var maxValue = calculateMaxValueFromMultipleArrays(multipleValueArray);
   var output = "";
   output += '<img src="http://chart.apis.google.com/chart?';
   output += 'chs=680x200';
   output += '&amp;cht=bvg';
   output += chartFormat['spacing'];
   output += '&amp;chxt=x,y';
   output += '&amp;chxr=1,0,' + maxValue;
   output += '&amp;chl=' + labelsInSortOrder(sortOrder);
   output += chartFormat['colors'];
   output += chartFormat['labels'];
   output += chartFormat['title'];
   output += '&amp;chd=' + simpleEncodeMultiple(multipleValueArray, maxValue);
   output += '" />';
   
   return output;
}

function outputTable(multipleValueArray, sortOrder)
{
   var output = "";
   output += "<table border=\"1\">";
   for (var i = 0; i < 26; ++i)
   {
      output += "<tr><td>" + alphabet.charAt(sortOrder.indexOf(i)) + "</td>";
      for (var j = 0; j < multipleValueArray.length; ++j)
      {
         output += "<td>" + multipleValueArray[j][i]  + "</td>";
      }
      output += "</tr>";
   }
   output += "</table>";
   
   return output;
}

function getSortOrderFromLetterArray(letters)
{
   // Bubblesort 'cause it's easier and the dataset will always be small.
   
   var sortOrder = new Array();
   for (var i = 0; i < 26; ++i)
   {
      sortOrder[i] = -1;
   }
   
   for (var i = 0; i < 26; ++i)
   {
      var high = -1;
      for (var j = 0; j < 26; ++j)
      {
         // if (sortOrder[j] < 0) 
         // {
            // console.log("where i=" + i + ", testing j(" + j + ")=" + letters[j] + " against high(" + high + ")=" + (high >= 0 ? letters[high] : "?"));
            // if (high < 0) console.log("high < 0, succeeding by default");
            // if (letters[j] > letters[high]) console.log("found new high value, " + letters[j] + " > " + letters[high]);
         // }
         if (sortOrder[j] < 0 && (high < 0 || parseInt(letters[j]) > parseInt(letters[high])))
         {
            high = j;
         }
      }
      sortOrder[high] = i;
   }
   
   for (var i = 0; i < 26; ++i)
   {
      console.log("sortOrder[" + i + "]: " + sortOrder[i]);
   }
   console.log("done");
   
   return sortOrder;
}

function getNaturalSortOrder()
{
   var sortOrder = new Array();
   for (var i = 0; i < 26; ++i)
   {
      sortOrder[i] = i;
   }
   return sortOrder;
}

function putIntoSortOrder(values, sortOrder)
{
   var sorted = new Array();
   for (var i = 0; i < 26; ++i)
   {
      sorted[sortOrder[i]] = values[i];
   }
   
   // for (var i = 0; i < 26; ++i)
   // {
      // console.log("sorted[" + i + "]: " + sorted[i]);
   // }
   
   return sorted;
}

function countTotalLetters(letters)
{
   var total = 0;
   for (var i = 0; i < letters.length; ++i)
   {
      total += parseInt(letters[i]);
   }
   return total;
}

function addUp(array)
{
   var total = 0;
   for (var i = 0; i < array.length; ++i)
   {
      total += array[i];
   }
   return total;
}

function getDelta(array1, array2)
{
   var total = 0;
   for (var i = 0; i < 26; ++i)
   {
      total += Math.abs(array1[i] - array2[i]);
   }
   return total;
}

var goButtonBehavior = Behavior.create
(
   {
      // Execute this function whenever the player clicks on a card.
      onclick : function()
      {
         count = 0;
         var wordList = splitTextIntoWords($F('words'));         
         var letters = countLettersInWords(wordList);
         var frequencies = calculateFrequencies(letters);
         
         count = 0;
         var uniqueWordList = splitTextIntoUniqueWords($F('words'));
         var lettersByWord = countLettersInWords(uniqueWordList);
         var frequenciesByWord = calculateFrequencies(lettersByWord);

         count = 0;
         var wordList2 = splitTextIntoWords($F('words2'));         
         var letters2 = countLettersInWords(wordList2);
         var frequencies2 = calculateFrequencies(letters2);
         
         count = 0;
         var uniqueWordList2 = splitTextIntoUniqueWords($F('words2'));
         var lettersByWord2 = countLettersInWords(uniqueWordList2);
         var frequenciesByWord2 = calculateFrequencies(lettersByWord2);
         
         count = countTotalLetters(('9|2|2|4|12|2|3|2|9|1|1|4|2|6|8|2|1|6|4|6|4|2|2|1|2|1').split('|'));
         var scrabbleLetters = ('9|2|2|4|12|2|3|2|9|1|1|4|2|6|8|2|1|6|4|6|4|2|2|1|2|1').split('|');
         var scrabbleFrequencies = calculateFrequencies(scrabbleLetters);
         
         count = countTotalLetters(('1|3|3|2|1|4|2|4|1|8|5|1|3|1|1|3|10|1|1|1|1|4|4|8|4|10').split('|'));
         var scrabblePoints = ('1|3|3|2|1|4|2|4|1|8|5|1|3|1|1|3|10|1|1|1|1|4|4|8|4|10').split('|');
         var scrabbleRelativePoints = calculateFrequencies(scrabblePoints);
         
         count = countTotalLetters(('8.2|1.5|2.8|4.3|12.7|2.2|2.0|6.1|7.0|0.2|0.8|4.0|2.4|6.7|7.5|1.9|0.1|6.0|6.3|9.1|2.8|1.0|2.4|0.2|2.0|0.1').split('|'));
         var cryptoLetters = ('8.2|1.5|2.8|4.3|12.7|2.2|2.0|6.1|7.0|0.2|0.8|4.0|2.4|6.7|7.5|1.9|0.1|6.0|6.3|9.1|2.8|1.0|2.4|0.2|2.0|0.1').split('|');
         var cryptoFrequencies = calculateFrequencies(cryptoLetters);
         
         var sortOrder = getSortOrderFromLetterArray(lettersByWord);
         var sortOrder2 = getSortOrderFromLetterArray(lettersByWord2);
         var scrabbleSortOrder = getSortOrderFromLetterArray(scrabbleLetters);
         var cryptoSortOrder = getSortOrderFromLetterArray(cryptoLetters);
         var naturalSortOrder = getNaturalSortOrder();
         
         var output = "<br/><br/>";
         
         var multipleValueArray = new Array();
         multipleValueArray.push(putIntoSortOrder(frequenciesByWord, sortOrder));
         multipleValueArray.push(putIntoSortOrder(frequencies, sortOrder));
         chartFormat['labels'] = "&amp;chdlp=b&amp;chdl=Frequency+by+Word|Frequency+by+Letter";
         chartFormat['title'] = "&amp;chtt=Frequency+in+First+Text+by+Word+and+Letter";
         chartFormat['spacing'] = "&amp;chbh=10,0,4";
         
         output += outputAnalysis(multipleValueArray, sortOrder);
         output += "<br/><br/>";
         
         var multipleValueArray = new Array();
         multipleValueArray.push(putIntoSortOrder(frequenciesByWord, sortOrder));
         multipleValueArray.push(putIntoSortOrder(scrabbleFrequencies, sortOrder));
         chartFormat['labels'] = "&amp;chdlp=b&amp;chdl=Frequency+by+Word|Scrabble+Frequency";
         chartFormat['title'] = "&amp;chtt=Frequency+in+First+Text+and+Scrabble";
         
         output += outputAnalysis(multipleValueArray, sortOrder);
         output += "<br/><br/>";
         
         var multipleValueArray = new Array();
         multipleValueArray.push(putIntoSortOrder(frequenciesByWord2, sortOrder2));
         multipleValueArray.push(putIntoSortOrder(frequencies2, sortOrder2));
         chartFormat['labels'] = "&amp;chdlp=b&amp;chdl=Frequency+by+Word|Frequency+by+Letter";
         chartFormat['title'] = "&amp;chtt=Frequency+in+Second+Text+by+Word+and+Letter";
         
         output += outputAnalysis(multipleValueArray, sortOrder2);
         output += "<br/><br/>";
         
         var multipleValueArray = new Array();
         multipleValueArray.push(putIntoSortOrder(frequenciesByWord2, sortOrder2));
         multipleValueArray.push(putIntoSortOrder(scrabbleFrequencies, sortOrder2));
         chartFormat['labels'] = "&amp;chdlp=b&amp;chdl=Frequency+by+Word|Scrabble+Frequency";
         chartFormat['title'] = "&amp;chtt=Frequency+in+Second+Text+and+Scrabble";
         
         output += outputAnalysis(multipleValueArray, sortOrder2);
         output += "<br/><br/>";
         
         var multipleValueArray = new Array();
         multipleValueArray.push(putIntoSortOrder(scrabbleFrequencies, scrabbleSortOrder));
         multipleValueArray.push(putIntoSortOrder(frequencies, scrabbleSortOrder));
         multipleValueArray.push(putIntoSortOrder(frequenciesByWord, scrabbleSortOrder));
         chartFormat['labels'] = "&amp;chdlp=b&amp;chdl=Tile+Frequency+in+Scrabble|Letter+Frequency+in+Text|Letter+Frequency+in+Text+(Unique+Words)";
         chartFormat['title'] = "&amp;chtt=Frequency+Compared+to+First+Text";
         chartFormat['spacing'] = "&amp;chbh=7,0,3";
         
         output += outputAnalysis(multipleValueArray, scrabbleSortOrder);
         output += "<br/><br/>";
         
         var multipleValueArray = new Array();
         multipleValueArray.push(putIntoSortOrder(scrabbleFrequencies, scrabbleSortOrder));
         multipleValueArray.push(putIntoSortOrder(frequencies2, scrabbleSortOrder));
         multipleValueArray.push(putIntoSortOrder(frequenciesByWord2, scrabbleSortOrder));
         chartFormat['labels'] = "&amp;chdlp=b&amp;chdl=Tile+Frequency+in+Scrabble|Letter+Frequency+in+Text|Letter+Frequency+in+Text+(Unique+Words)";
         chartFormat['title'] = "&amp;chtt=Frequency+Compared+to+Second+Text";
         chartFormat['spacing'] = "&amp;chbh=7,0,3";
         
         output += outputAnalysis(multipleValueArray, scrabbleSortOrder);
         output += "<br/><br/>";
         
         var multipleValueArray = new Array();
         multipleValueArray.push(putIntoSortOrder(frequenciesByWord, sortOrder));
         multipleValueArray.push(putIntoSortOrder(scrabbleRelativePoints, sortOrder));
         chartFormat['labels'] = "&amp;chdlp=b&amp;chdl=Frequency+by+Word|Relative+Point+Value";
         chartFormat['title'] = "&amp;chtt=Frequency+in+First+Text+and+Value";
         chartFormat['spacing'] = "&amp;chbh=10,0,4";
         
         output += outputAnalysis(multipleValueArray, sortOrder);
         output += "<br/><br/>";
         
         var multipleValueArray = new Array();
         multipleValueArray.push(putIntoSortOrder(frequenciesByWord2, sortOrder2));
         multipleValueArray.push(putIntoSortOrder(scrabbleRelativePoints, sortOrder2));
         chartFormat['labels'] = "&amp;chdlp=b&amp;chdl=Frequency+by+Word|Relative+Point+Value";
         chartFormat['title'] = "&amp;chtt=Frequency+in+Second+Text+and+Value";
         chartFormat['spacing'] = "&amp;chbh=10,0,4";
         
         output += outputAnalysis(multipleValueArray, sortOrder2);
         output += "<br/><br/>";
         
         var multipleValueArray = new Array();
         multipleValueArray.push(putIntoSortOrder(scrabbleFrequencies, scrabbleSortOrder));
         multipleValueArray.push(putIntoSortOrder(scrabbleRelativePoints, scrabbleSortOrder));
         chartFormat['labels'] = "&amp;chdlp=b&amp;chdl=Frequency+of+Tile|Relative+Point+Value";
         chartFormat['title'] = "&amp;chtt=Frequency+in+Scrabble+and+Value";
         
         output += outputAnalysis(multipleValueArray, scrabbleSortOrder);         
         //output += "<br/><br/>";
         
         //var multipleValueArray = new Array();
         //multipleValueArray.push(putIntoSortOrder(frequenciesByWord, naturalSortOrder));
         //multipleValueArray.push(putIntoSortOrder(frequencies, naturalSortOrder));
         //multipleValueArray.push(putIntoSortOrder(scrabbleFrequencies, naturalSortOrder));
         
         //output += outputTable(multipleValueArray, naturalSortOrder);       
         output += "<br/><br/>";
         
         // Points

         var tilesByPoint = ('68|7|8|10|1|0|0|2|0|2').split('|');
         var maxValue = 100;
         output += '<img src="http://chart.apis.google.com/chart?';
         output += 'chs=680x200';
         output += '&amp;cht=bvg';
         output += '&amp;chbh=60,0,4';
         output += '&amp;chxt=x,y';
         output += '&amp;chxr=1,0,' + maxValue;
         output += '&amp;chl=1|2|3|4|5|6|7|8|9|10';
         output += chartFormat['colors'];
         output += '&amp;chdlp=b&amp;chdl=Tile+Frequency';
         output += '&amp;chtt=Frequency+of+Tiles+by+Point+Value';
         output += '&amp;chd=t:68,7,8,10,1,0,0,2,0,2';
         output += '" />';
         output += "<br/><br/>";
         
         // Point distribution
         output += '<img src="http://chart.apis.google.com/chart?chs=680x200&cht=bvg&chbh=60,0,4&chxt=x,y&chxr=1,0,100&chl=1|2|3|4|5|6|7|8|9|10&chco=ff0000,ffbb66,aa6622,00bbbb&chdlp=b&chdl=Total+Points&chtt=Point+Distribution&chd=t:68,14,24,40,5,0,0,16,0,20" />';
         output += "<br /><br />";
         
         var multipleValueArray = new Array();
         multipleValueArray.push(putIntoSortOrder(scrabbleFrequencies, scrabbleSortOrder));
         chartFormat['labels'] = "&amp;chdlp=b&amp;chdl=Tile+Frequency";
         chartFormat['title'] = "&amp;chtt=Frequency+of+Tiles";
         chartFormat['spacing'] = "&amp;chbh=20,0,4";
         
         output += outputAnalysis(multipleValueArray, scrabbleSortOrder);
         output += "<br/><br/>";
         
         var multipleValueArray = new Array();
         multipleValueArray.push(putIntoSortOrder(scrabbleFrequencies, scrabbleSortOrder));
         multipleValueArray.push(putIntoSortOrder(cryptoFrequencies, scrabbleSortOrder));
         chartFormat['labels'] = "&amp;chdlp=b&amp;chdl=Tile+Frequency+in+Scrabble|Letter+Frequency+in+English";
         chartFormat['title'] = "&amp;chtt=Frequency+Compared+to+English";
         chartFormat['spacing'] = "&amp;chbh=10,0,4";
         
         output += outputAnalysis(multipleValueArray, scrabbleSortOrder);
         output += "<br/><br/>";
         
         var multipleValueArray = new Array();
         multipleValueArray.push(putIntoSortOrder(frequencies, sortOrder));
         multipleValueArray.push(putIntoSortOrder(frequencies2, sortOrder));
         chartFormat['labels'] = "&amp;chdlp=b&amp;chdl=Frequencies+in+First+Text|Frequencies+in+Second+Text";
         chartFormat['title'] = "&amp;chtt=Comparison+of+Texts+by+Letter";
         chartFormat['spacing'] = "&amp;chbh=10,0,4";
         
         output += outputAnalysis(multipleValueArray, sortOrder);
         output += "<br/><br/>";
         
         var multipleValueArray = new Array();
         multipleValueArray.push(putIntoSortOrder(frequenciesByWord, sortOrder));
         multipleValueArray.push(putIntoSortOrder(frequenciesByWord2, sortOrder));
         chartFormat['labels'] = "&amp;chdlp=b&amp;chdl=Frequencies+in+First+Text|Frequencies+in+Second+Text";
         chartFormat['title'] = "&amp;chtt=Comparison+of+Texts+by+Word";
         chartFormat['spacing'] = "&amp;chbh=10,0,4";
         
         output += outputAnalysis(multipleValueArray, sortOrder);
         output += "<br/><br/>";
         
         var multipleValueArray = new Array();
         multipleValueArray.push(putIntoSortOrder(frequencies, sortOrder));
         multipleValueArray.push(putIntoSortOrder(frequencies2, sortOrder));
         multipleValueArray.push(putIntoSortOrder(cryptoFrequencies, sortOrder));
         chartFormat['labels'] = "&amp;chdlp=b&amp;chdl=Frequencies+in+First+Text|Frequencies+in+Second+Text|Letter+Frequency+in+English";
         chartFormat['title'] = "&amp;chtt=Verification+of+Crypography";
         chartFormat['spacing'] = "&amp;chbh=7,0,3";
         
         output += outputAnalysis(multipleValueArray, sortOrder);
         output += "<br/><br/>";
         
         var multipleValueArray = new Array();
         multipleValueArray.push(putIntoSortOrder(frequenciesByWord, sortOrder));
         multipleValueArray.push(putIntoSortOrder(frequenciesByWord2, sortOrder));
         multipleValueArray.push(putIntoSortOrder(cryptoFrequencies, sortOrder));
         chartFormat['labels'] = "&amp;chdlp=b&amp;chdl=Frequencies+in+First+Text+by+Word|Frequencies+in+Second+Text+by+Word|Letter+Frequency+in+English";
         chartFormat['title'] = "&amp;chtt=Comparison+of+English+Language+with+Unique+Words";
         chartFormat['spacing'] = "&amp;chbh=7,0,3";
         
         output += outputAnalysis(multipleValueArray, sortOrder);
         
         $('output').innerHTML = output;
      }
   }
);

Event.addBehavior
(
   {
      '.countByLetterButton' : goButtonBehavior
   }
);

Event.onReady
(
   function()
   {
      console.log('start');
   }
);
