/*
  filename:	buzzword.js
  version:	1.2
  last modified:	27.09.2007
  author:	Axel Schneider
  mail:     mail@axelschneider.info
  www:	   	http://axelschneider.info
            http://jsBuzzwords.axelschneider.info

  summary:	This script inserts buzzwords into a given html-container. The height of the buzzwords depends on
  		    a number (e.g. a buzzword-counter) which is set in relation to the summed-up-number of all buzzwords.

  history:	10.04.2007 initial version.
  		    24.04.2007 added title-information to all buzzwords
  		    27.09.2007 added extra parameter (maxBuzzwordRelativeNumber) for showing extra tall buzzwords

  usage:	Create a javascript-array which consists the buzzword-information as 2-dimensional array. The first
  		    dimension consists of the name of the buzzword and the second one of an absolute number. Bind the
            buzzwords to a html-container by calling the appropriate javascript-function 'fillBuzzwordContainer'.

  example:	1. build a html-container for the buzzwords
  		    <div id="buzzwordsUser"></div>

  		    2. create the javascript-array
  		    var bwUser = new Array();
  			bwUser[0] = new Array("Werner", 10);
  			bwUser[1] = new Array("Maggie", 150);
  			bwUser[2] = new Array("Jonas", 280);
  			bwUser[3] = new Array("Jule", 34);

        	3. call javascript-function 'fillBuzzwordContainer'
        	fillBuzzwordContainer("buzzwordsUser", bwUser, 0.7, 5.0);
        	
  hints:	You may vary the style of showing the buzzwords which are bigger than the max-allowed size by
            changing the variable "maxEntry" in the function "fillBuzzwordContainer".
*/


/*
  Builds a collection of buzzword-entries into a given html-container.
  	- idOfContainer (type: string): The id of the html-container.
    - arrayWithBuzzwords (type: array with 2 dimensions) : The array which holds the information about the buzzwords.
      The first dimension consists of the buzzword and the second one of an absolute number.
    - minBuzzwordRelativeNumber (type: float) : The value which indicates how big the relative count of a buzzword
      has to be to be visible.
    - maxBuzzwordRelativeNumber (type: flot) : The value which indicated how big the relative size of a buzzword 
      should be to be shown as extra-tall-buzzword.
*/
function fillBuzzwordContainer(idOfContainer, arrayWithBuzzwords, minBuzzwordRelativeNumber, maxBuzzwordRelativeNumber)
{
  //check parameters
  var msg = checkBuzzwordParameters(idOfContainer, arrayWithBuzzwords, minBuzzwordRelativeNumber, maxBuzzwordRelativeNumber);
  if(msg.length>0)
  {
    alert(msg);
    return;
  }

  var container = document.getElementById(idOfContainer);
  var content = "";
  var entry = "<span style=\"font-size:#0#em;white-space:nowrap;\" title=\"#1#\">#2#</span>";
  var maxEntry = "<span style=\"font-weight:bold;\">#0#</span>";

  //get minBuzzwordRelativeNumber
  minBuzzwordRelativeNumber=parseFloat(minBuzzwordRelativeNumber);

  //exchange absolute numbers to relative numbers
  arrayWithBuzzwords = exchangeAbsoluteNumbersByRelativeNumbers(arrayWithBuzzwords, minBuzzwordRelativeNumber);

  //sort by buzzwords
  arrayWithBuzzwords.sort();

  //build the html-content for the buzzword-container
  var numCssHeight, strBuzzword;
  for(var i=0; i<arrayWithBuzzwords.length; i++)
  {
    if(arrayWithBuzzwords[i][1]>minBuzzwordRelativeNumber)
    {
	  strBuzzword = arrayWithBuzzwords[i][0];
	  numCssHeight = arrayWithBuzzwords[i][1];
	  
	  //check if buzzword is bigger than the max allowed size
	  if(numCssHeight>=maxBuzzwordRelativeNumber)
	  {
	  	numCssHeight = maxBuzzwordRelativeNumber;
		strBuzzword = maxEntry.replace(/#0#/, strBuzzword);		
	  }
	  
      content+=entry.replace(/#0#/, numCssHeight).replace(/#1#/, arrayWithBuzzwords[i][0]).replace(/#2#/, strBuzzword);
      content+=(i+1<arrayWithBuzzwords.length)?"&nbsp;\n":"";	  
    }
  }

  //fill the buzzword-container with the html-content
  container.innerHTML = content;
}

/*
  Checks the given parameters of type-savety and value-consistency. Returns a message which contains all errors
  that occured during the check.
*/
function checkBuzzwordParameters(idOfContainer, arrayWithBuzzwords, minBuzzwordRelativeNumber, maxBuzzwordRelativeNumber)
{
  var msg = "";

  //param idOfContainer
  if(document.getElementById(idOfContainer)===null)
    msg = "The given id of the buzzword-container ("+idOfContainer+") does not exist!\n";

  //param arrayWithBuzzwords
  if(isOfTypeArray(arrayWithBuzzwords))
  {
    if(arrayWithBuzzwords.length>0)
    {
      for(var i=0; i<arrayWithBuzzwords.length; i++)
      {
        if(isOfTypeArray(arrayWithBuzzwords[0]))
        {
          if(arrayWithBuzzwords[i].length==2)
          {
             if(typeof(arrayWithBuzzwords[i][0])=="string")
             {
               if(arrayWithBuzzwords[i][0].length===0)
                 msg += "The 1. dimension of the "+i+". index of the parameter 'arrayWithBuzzwords' is empty!\n";
             }
             else
               msg += "The 1. dimension of the "+i+". index of the parameter 'arrayWithBuzzwords' is not a string!\n";

             if(typeof(arrayWithBuzzwords[i][1])=="number")
             {
               if(parseFloat(arrayWithBuzzwords[i][1])<=0)
                 msg += "The 2. dimension of the "+i+". index of the parameter 'arrayWithBuzzwords' should be bigger than 0!\n";
             }
             else
               msg += "The 2. dimension of the "+i+". index of the parameter 'arrayWithBuzzwords' is not a number!\n";
          }
          else
            msg += "The "+i+". index of the parameter 'arrayWithBuzzwords' does not have 2 dimensions!\n";
        }
        else
          msg += "The "+i+". index of the parameter 'arrayWithBuzzwords' is not of type Array!\n";
      }
    }
  }
  else
    msg += "The param 'arrayWithBuzzwords' is not of type Array!\n";

  //param minBuzzwordRelativeNumber
  if(String(parseFloat(minBuzzwordRelativeNumber))=="NaN")
    msg += "The param 'minBuzzwordRelativeNumber' is not a number!";
	
  //param minBuzzwordRelativeNumber
  if(String(parseFloat(maxBuzzwordRelativeNumber))=="NaN")
    msg += "The param 'maxBuzzwordRelativeNumber' is not a number!";

  return msg;
}

/*
  Returns true, if the given parameter is of type Array otherwise false.
*/
function isOfTypeArray(obj)
{
  return (obj.constructor && obj.constructor.toString().search('Array')>-1);
}

/*
  Exchanges the absolute values of buzzword-occurence by relative values. So the css-height of the buzzwords could be
  managed. Returns the same input-array which consist of the relative values.
*/
function exchangeAbsoluteNumbersByRelativeNumbers(arrayWithBuzzwords)
{
  var numberOfBW = arrayWithBuzzwords.length;
  var numberOfAllBWCounts = 0;

  //get number of all buzzword-counts
  for(var i=0; i<arrayWithBuzzwords.length; i++)
  {
    numberOfAllBWCounts+=arrayWithBuzzwords[i][1];
  }

  //echange absolute number by relative-number
  for(var i=0; i<arrayWithBuzzwords.length; i++)
  {
    arrayWithBuzzwords[i][1] = arrayWithBuzzwords[i][1]/numberOfAllBWCounts*arrayWithBuzzwords.length;
  }

  return arrayWithBuzzwords;
}
