/**************************************************************************** 
 * This notice must be untouched at all times.
 *
 * Soanpan.js    v. 2.0
 *
 * Copyright (c) 2007  Alexandru M. Tertisco. All rights reserved.
 *
 *  \ \__                      /\_ \       /'__`\                           
 * \ \ ,_\    __   _ __    __  \//\ \     /\_\L\ \  __  _      _ __   ___   
 *  \ \ \/  /'__`\/\`'__\/'__`\  \ \ \    \/_/_\_<_/\ \/'\    /\`'__\/ __`\ 
 *   \ \ \_/\  __/\ \ \//\ \L\.\_ \_\ \_  __/\ \L\ \/>  </  __\ \ \//\ \L\ \
 *    \ \__\ \____\\ \_\\ \__/.\_\/\____\/\_\ \____//\_/\_\/\_\\ \_\\ \____/
 *     \/__/\/____/ \/_/ \/__/\/_/\/____/\/_/\/___/ \//\/_/\/_/ \/_/ \/___/ 
 * 
 * Created January 2007 by Alexandru M. Tertisco. (Web: http://www.teral.3x.ro)
 * Last modified: Saturday, January 27, 2007
 * 
 *   _____________________________________________________
 *         __                                             
 *       /    )                                           
 *   ----\--------__----__----__-----------__----__----__-
 *        \     /   ) /   ) /   ) ===    /   ) /   ) /   )
 *   _(____/___(___/_(___(_/___/________/___/_(___(_/___/_
 *                                   /                  
 *            - the Chinese Abacus - 
 *
 *  O represents the bead; 
 *  | represents an empty position (the rod)
 *  = represents the frame
 *
 *   ROD
 *  ============= Row Position 
 *    O     0     Upper Deck Rows(Heaven rows)
 *    O     1
 *    |     2
 *  =============
 *    |     0
 *    O     1     Lower Deck (Earth rows)
 *    O     2
 *    O     3
 *    O     4
 *    O     5
 *  =============
 ****************************************************************************/
/* version info */
var SoanPanVersionInfo = "S o a n - p a n  1.0 Alpha - "+
                         "Copyright(©) 2007 A.M. Tertisco "+
												 "(http://teral.3x.ro)";
/* preloaded images */

	var bead = new Image();
	bead.src="images/bead.gif";
	
	var nobead = new Image();
	nobead.src="images/nobead.gif";

/************************** THE SOROBAN CLASS *******************************/
/**
 * Soroban class Constructor 
 */
function SoanPan(
      instanceName, /* the instance name */
			container, /* reference to the the DIV element to contain this instance */ 
			nRods, /* the number of soroban rods */
			//beadWidth, /* the bead image width */
			//beadHeight, /* the bead image height */
			caption /* the caption text to display */
		)
{
  /* Soroban Properties */
  this.name = instanceName;
	this.container = container;
	this.nRods = nRods<10?10:nRods;
	this.beadWidth = 35;
	this.beadHeight = 22;
	this.caption = caption;
	/* The Chinese abacus soroban has the configuration below*/
  this.nHeavenRows = 3;	/* two rows(2 bead, 1 gap on 'Heaven' upper deck)*/
  this.nEarthRows = 6;	/* five rows (5 beads, 1 gap on 'Earth' lower deck)*/
	/* Set container content */
	container.title=SoanPanVersionInfo;
	container.innerHTML = 	
  	"<table cellspacing='0' cellpading='0' >\n" + 
    "<tr><td><div id='"+instanceName+"Screen'></div></td></tr>\n" + 
    "<tr><td><div id='"+instanceName+"ControlPanel'></div></td></tr>\n" + 
    "</table>";
  
	/* Contained objects */
	this.upperDeck = new Array(); /* the 'Heaven' upper deck */
	this.lowerDeck = new Array(); /* the 'Earth' lower deck */  
  /* clear the upper deck */
	for(row=0;row<this.nHeavenRows;row++)
	{
	  this.upperDeck[row]=new Array();
		for(col=0;col<this.nRods;col++)
		{
			this.upperDeck[row][col]=(row==this.nHeavenRows-1?0:1);
		}
	}
	/* clear the lower deck */
	for(row=0;row<this.nEarthRows;row++)
	{
	  this.lowerDeck[row]=new Array();
		for(col=0;col<this.nRods;col++)
		{
			this.lowerDeck[row][col]=(row==0?0:1);
		}
	}
	this.screenContainer=document.getElementById(instanceName+"Screen");
  this.controlPanelContainer=document.getElementById(instanceName+"ControlPanel");
	
	this.screen = new SoanPanScreen(this);
	this.controlPanel = new SoanPanControlPanel(this);
	this.value = 0;
	this.maxValue = Math.pow(10,this.nRods)-1; /* maximum value */
	this.maxHexValue = Math.pow(16,this.nRods)-1; /* maximum value */
	this.controlPanel.display(0);
	/* Animation parameters */
	this.timeInterval=500; /* defines animation speed */
  this.timeout=null;
  this.animation = false; /* no animation */
  this.count=0; /* animation step counter */
	
	/* Event handlers */
	this.handleResetBtnClk = SoanPanHandleResetBtnClk;
	this.handleAnimateBtnClk = SoanPanHandleAnimateBtnClk;
	this.handleSpeedBtnClk = SoanPanHandleSpeedBtnClk;
	this.handleRadixChkBoxClk = SoanPanHandleRadixChkBoxClk;
	this.handleTopBeadClick = SoanPanHandleTopBeadClick;
	this.handleBottomBeadClick = SoanPanHandleBottomBeadClick;
	/* methods */
	this.reset = ResetSoanPan;
	this.clear = ClearSoanPan;
	this.animate = SoanPanAnimate;
}

      /**********************************
       * SoanPan methods implementation *
       **********************************/

/**
 * Reset SoanPan status 
 */
function ResetSoanPan()
{
 		/* clear the upper deck */
		for(row=0;row<this.nHeavenRows;row++)
		{
		 	for(col=0;col<this.nRods;col++)
			{
					this.upperDeck[row][col]=(row==this.nHeavenRows-1?0:1);
			}
		}
		/* clear the lower deck */
		for(row=0;row<this.nEarthRows;row++)
		{
		 	for(col=0;col<this.nRods;col++)
			{
					this.lowerDeck[row][col]=(row==0?0:1);
			}
		}
		this.value = 0;
}

/**
 * SoanPan animation - counts from 0 to 10^nRods - 1
 */
function SoanPanAnimate()
{
  this.reset();
	/* set SoanPan according to the current animation step counter value */
	var val = this.count; /* current value to display */
	/* set the SoanPan status arrays (upperDeck and lowerDeck) according 
	   to the new value to display */
	for(col = this.nRods-1; col >= 0; col--)
	{
	   if(val == 0)
		 { /* 0 - nothing to set. Skip setting next rods (already set to 0)*/
		   break;
		 }
  	 rem = Math.floor(val % 10); /* reminder */
  	 val = Math.floor(val/10); /* next value*/
  	 lower = Math.floor(rem%5); /* lower deck value (base 5)*/
  	 upper = (rem < 5? 0:1); /* upper deck value (base 5)*/
		 /* set upper deck */
  	 this.upperDeck[1][col]= 1-upper; //complement
  	 this.upperDeck[2][col]= upper;
		 /* set lower deck */
  	 row = lower; /* rod row to remove bead. */  
  	 if(row!=0)
  	 {   /* not empty row - make it empty. Remove bead and move it to row 0 */
    		 this.lowerDeck[row][col]= 0; /* remove */
    		 this.lowerDeck[0][col]= 1; /* place to empty row 0 */
 		 } 
	}
	this.screen.update(); /* update GUI */
	this.controlPanel.display(this.count); /* display current counter value */
	/* increment counter and truncate to max value to avoid overflow */
	this.count = (this.count+1)%(this.maxValue+1);
	/* reschedule next animation step */
	this.timeout = setTimeout(this.name+".animate()",this.timeInterval);	
}
/**
 * SoanPan animation - counts from 0 to 16^nRods - 1
 */
function SoanPanAnimate()
{
  this.reset();
	/* set SoanPan according to the current animation step counter value */
	var val = this.count; /* current value to display */
	/* set the SoanPan status arrays (upperDeck and lowerDeck) according 
	   to the new value to display */
	for(col = this.nRods-1; col >= 0; col--)
	{
	   if(val == 0)
		 { /* 0 - nothing to set. Skip setting next rods (already set to 0)*/
		   break;
		 }
  	 rem = Math.floor(val % 16); /* reminder */
  	 val = Math.floor(val/16); /* next value*/
  	 lower = (rem%6); /* lower deck value (base 5)*/
		 if(rem<=5)
		 {
		   upper = 0;
		  } 
			else if (rem <= 10)
		  {
			  upper=1;
			}
			else
			{
			  upper = 2;
			}
  	 /* set upper deck */
		 row = 2-upper;
		 if(row!=2)
  	 {   /* not empty row - make it empty. Remove bead and move it to row 0 */
    		 this.upperDeck[row][col]= 0; /* remove */
    		 this.upperDeck[2][col]= 1; /* place to empty row 2 */
 		 } 
		 /* set lower deck */
  	 row = lower; /* rod row to remove bead. */  
  	 if(row!=0)
  	 {   /* not empty row - make it empty. Remove bead and move it to row 0 */
    		 this.lowerDeck[row][col]= 0; /* remove */
    		 this.lowerDeck[0][col]= 1; /* place to empty row 0 */
 		 } 
	}
	this.screen.update(); /* update GUI */
	this.controlPanel.display(this.count); /* display current counter value */
	/* increment counter and truncate to max value to avoid overflow */
	this.count = (this.count+1)%(this.maxHexValue+1);
	/* reschedule next animation step */
	this.timeout = setTimeout(this.name+".animate()",this.timeInterval);	
}
/**
 * Handle 'Reset' button click event.
 */
function SoanPanHandleResetBtnClk()
{
  this.clear();
}

/**
 * Clear SoanPan.
 */
function ClearSoanPan()
{
	this.reset(); /* clear status arrays and value */
	this.screen.update(); /* update screen */
	this.controlPanel.display(0); /* clear control panel text display */
}
          /******************************
           * SoanPan GUI event handlers *
           ******************************/
/**
 * Handle 'Animate' button click event. 
 */
function SoanPanHandleAnimateBtnClk()
{
  if(!this.animation)
	{  /* animation is not running. */
		 this.animation=true; /* set flag to indicate animation is running */
		 this.count = 0; /* clear animation step counter */
		 /* change Animation button label to 'Stop' */
	   this.controlPanel.animateBtn.value = "   Stop   "; 
		 this.controlPanel.resetBtn.disabled=true; /* disable reset button */
		 this.controlPanel.resetBtn.style.cursor = "default";
		 this.controlPanel.speedBtn.disabled=false; /* enable speed control button */
		 this.controlPanel.speedBtn.style.cursor = "hand";
		 /* reschedule running the animation method in 100ms*/
		 this.timeout = setTimeout(this.name+".animate()",100);	 
	}
	else
	{  /* animation is in progress. */
	   this.animation=false; /* set flag to indicate animation is not running */
		 /* change Animation button label back to 'Animate' */
	   this.controlPanel.animateBtn.value = "Animate";
		 /* reset animation time interval to default 500ms (fast)*/
		 this.timeInterval = 500; 
		 this.controlPanel.resetBtn.disabled=false; /* enable reset button */
		 this.controlPanel.resetBtn.style.cursor = "hand";
		 this.controlPanel.speedBtn.disabled=true; /* disable speed control button */
		 this.controlPanel.speedBtn.style.cursor = "default";
		 /* change spead control button label to 'Slower' (default) */
	   this.controlPanel.speedBtn.value = "Slower ";
		 clearTimeout(this.timeout); /* clear timeout */
		 this.clear(); /* clear SoanPan */
	}
}

/**
 * Handle speed control button click event. 
 */
function SoanPanHandleRadixChkBoxClk()
{
   this.clear();
	 this.count=0;
}
/**
 * Handle speed control button click event. 
 */
function SoanPanHandleSpeedBtnClk()
{
  if(this.timeInterval==500)
	{ /* 'fast' mode animation in progress. Change to 'slow' mode  */
	 	this.timeInterval=1000; /*  set 'slow' mode timeout interval - 1000ms*/
		/* change spead control button label to 'Faster' */
		this.controlPanel.speedBtn.value = "Faster ";
	}
	else
	{ /* 'slow' mode animation in progress. Change to 'fast' mode  */
	 	this.timeInterval=500; /*  set 'fast' mode timeout interval - 500ms*/
		/* change spead control button label to 'Slower' */
		this.controlPanel.speedBtn.value = "Slower ";
	}
}

/**
 * Handle upper deck beads click event. 
 * args: row, col - the upper deck clicked bead's row and column 
 */ 
function SoanPanHandleTopBeadClick(row, col)
{  
  if(this.upperDeck[row][col]!=0)
	{
	 	var empty;
		/* search the empty rod position */
		for(_row=0;_row<this.nHeavenRows;_row++)
		{
		  if(this.upperDeck[_row][col]==0)
			{ /* found */
			  empty=_row;
				break;
			}
		}
		/* swap the clicked bead and empty place on the screen*/
		document.getElementById(this.name+"Top"+row+col).src=nobead.src;
		document.getElementById(this.name+"Top"+empty+col).src=bead.src;
		/* swap the clicked bead and empty place elements in the upperDeck array*/
		this.upperDeck[empty][col]=1;
		this.upperDeck[row][col]=0;
		/* calculate the new value */
		base= this.controlPanel.radixChkBox.checked?16:10;
		expn=this.nRods-col-1; /* exponent - power of base*/
		this.value += (empty-row )*5 * Math.pow(base,expn); /* store the new value */
		this.controlPanel.display(this.value); /* display the new value */
		
	}
}

/**
 * Handle lower deck beads click event. 
 * args: row, col - the lower deck clicked bead's row and column 
 */ 
function SoanPanHandleBottomBeadClick(row, col)
{
   if(this.lowerDeck[row][col]!=0)
	 {
  	 	var empty;
  		for(_row=0;_row<this.nEarthRows;_row++)
  		{
  		  if(this.lowerDeck[_row][col]==0)
  			{
  			  empty=_row;
  				break;
  			}
  		}
			
  		document.getElementById(this.name+"Bot"+row+col).src=nobead.src;
  		document.getElementById(this.name+"Bot"+empty+col).src=bead.src;
			
  		this.lowerDeck[empty][col]=1;
  		this.lowerDeck[row][col]=0;
  		expn=this.nRods-col-1
			base= this.controlPanel.radixChkBox.checked?16:10;
			this.value +=(row-empty ) * Math.pow(base,expn);
			this.controlPanel.display(this.value);
	 }
}

/************************* SoanPan SCREEN CLASS *****************************/
/** 
 * SoanPan Screen constructor 
 * argument: parent - the reference to SoanPan parent class.
 */
function SoanPanScreen(parent)
{
    this.parent= parent;
    this.nCols = this.parent.nRods; /* number of upper and lower deck columns */
		var innerHTML= new String("");
	  /* The SoanPan frame as HTML table*/
		innerHTML +='<table cellspacing="0" cellpading="0" border="4" '+
		            'style="background-color: gray;">'+
		            '<caption>'+ this.parent.caption + '</caption><tr><td>';
		/* The 'Heaven' uper deck frame as HTML table*/
		innerHTML += '<table cellspacing="0" cellpading="0" border="0" '+
		             'style="background-color: white;">';
    /* place the upper deck bead images */
		for(row=0;row<this.parent.nHeavenRows;row++)
		{  
		 	for(col=0;col<this.parent.nRods;col++)
			{
			 	innerHTML+='<td style="width: '+ this.parent.beadWidth+'; height: '+ 
				  this.parent.beadHeight+'; padding: 0px;"><image id="'+ 
					this.parent.name+'Top'+
					row+col+'" src='+
					(row==this.parent.nHeavenRows-1?"images/nobead.gif":"images/bead.gif")+
					' style="margin: 0px ;width: '+ 
					this.parent.beadWidth+'; height: '+ this.parent.beadHeight+'; ' +
					'cursor: '+(row==this.parent.nHeavenRows-1?'default;':'hand;') + 
					'" OnClick="'+ this.parent.name+'.handleTopBeadClick('+row+','+
					col+')"/></td>';
			}
			innerHTML+='</tr>';
		}
		innerHTML+='</table></td></tr><tr><td>';
		
		/* The 'Earth' lower deck frame as HTML table*/
		innerHTML+='<table cellspacing="0" cellpading="0" border="0" '+
		           'style="background-color: white;">';
		/* place the lower deck bead images */
		for(row=0;row<this.parent.nEarthRows;row++)
		{
		 	for(col=0;col<this.parent.nRods;col++)
			{
			 	innerHTML+='<td style="width: '+ this.beadWidth+'; height: '+ 
				  this.parent.beadHeight+'; padding: 0px;"><image id="'+ 
					this.parent.name+'Bot'+
					row+col+'" src='+(row==0?"images/nobead.gif":"images/bead.gif")+
					' style="margin: 0px ; width: '+ 
					this.parent.beadWidth+'; height: '+ this.parent.beadHeight+';' +
					'cursor: ' + (row==0? 'default;':'hand;')+
					'" OnClick="'+ this.parent.name+'.handleBottomBeadClick('+row+','+
					col+')"/></td>';
			}
			innerHTML+='</tr>';
		}
		innerHTML+='</table></td></tr></table>';
		
		/* fill the SoanPan screen container DIV with the inner HTML content 
		   to be displayed */
		this.parent.screenContainer.innerHTML=innerHTML; 	
		/* class methods */
		this.update = UpdateSoanPanScreen; 
}

/** 
 * updates the SoanPan screen according to upperDeck and lowerDeck arrays
 */
function UpdateSoanPanScreen()
{
 	  /* set the upper deck GUI*/
		for(row=0;row<this.parent.nHeavenRows;row++)
		{
		  for(col=0;col<this.parent.nRods;col++)
			{
				document.getElementById(this.parent.name+"Top"+row+col).src=
				  (this.parent.upperDeck[row][col]==0?nobead.src:bead.src);
			}
		}
		/* set the lower deck GUI*/
		for(row=0;row<this.parent.nEarthRows;row++)
		{
		 	for(col=0;col<this.parent.nRods;col++)
			{
			  document.getElementById(this.parent.name+"Bot"+row+col).src=
				  (this.parent.lowerDeck[row][col]==0?nobead.src:bead.src);
			}
		}
}

/**************************** SoanPan CONTROL PANEL CLASS *******************/

/**
 * SoanPan Control panel constructor 
 * argument: parent - the reference to SoanPan parent class.
 */
function SoanPanControlPanel(parent)
{
  this.parent = parent;
	/* generates control panel innerHTML code */
	var innerHTML = new String(
  	"    <table width='100%' cellspacing='0' cellpadding='2'  frame='box'>\n" + 
    "      <tr style='font-size:12px ; text-align: center; background-color: "+
		"darkgray; color: white;' >\n"); 
	for(expN=parent.nRods-1;expN>=0;expN--)
	{ 
	  innerHTML+="        <td " + 
		(expN<2?"style='background-color: black ;'":"")+ 
		" >10<sup>"+(expN-2)+"</sup></td>\n"; 
	}
	this.textDisplaySize = parent.nRods + Math.floor(parent.nRods/2);
  innerHTML+="      </tr>\n" + 
  "      <tr style='background-color: silver;' >\n" + 
  "        <td colspan='"+this.parent.nRods+"' >\n" + 
  "      	<form >\n" + 
  "          <input type='text'  size='" + this.textDisplaySize + 
	"' id='"+parent.name+"TextDisplay' />\n" +
  "        	<input type='button' value=' Reset ' id='" +
	  parent.name + "ResetBtn' style='cursor: Hand;'\n" + 
  "					       onclick='"+parent.name+".handleResetBtnClk();' />\n" + 
  "					<input type='button' value='Animate' id='" + 
	  parent.name+"AnimateBtn' style='cursor: Hand;'\n" + 
  "					       onClick='"+parent.name+".handleAnimateBtnClk()' />\n" + 
  "					<input type='button' value='Slower ' id='" + 
	  parent.name + "SpeedBtn' \n" + 
  "					       onClick='"+parent.name+".handleSpeedBtnClk()'  " + 
	"disabled='disabled' /><br />\n" +
	
	"        	<input type='checkbox' value='Hex' id='" +
	  parent.name + "RadixChkBox' \n "+ 
  "					       onClick='"+parent.name+".handleRadixChkBoxClk()'  " + 
	"/> Base 16\n" +  
  "        </form>\n" +"      	</td>\n" + "      </tr>\n" + "    </table>";
	/* fill the DIV container element with the control panel HTML code */
	parent.controlPanelContainer.innerHTML = innerHTML;
	
	/* store reference to text display element */
	this.textDisplay = document.getElementById(parent.name+"TextDisplay"); 
	/* generate initial value display string '0.000.000. ... .000'*/
	var initialString = new String(",00");
	var separator = '.';
	for(rod=1;rod<= parent.nRods-1;rod++)
	{
		initialString = ((rod%3 == 0)&& (rod != parent.nRods-1) ? separator:'')+
			                + '0'+ initialString;
	}
	this.initialString = initialString; /* store initial string */
	/* generate initial value display string '00:00:00:0 ... 0:00'*/
	var initialHexString = new String("");
	var separator = ':';
	for(rod=1;rod<= parent.nRods;rod++)
	{
		initialHexString = ((rod%2 == 0)&& (rod != parent.nRods) ? separator:'')+
			                + '0'+ initialHexString;
	}
	this.initialHexString = initialHexString; /* store initial string */
	/* init the control panel text display */
	this.textDisplay.value = initialString;
	/* methods */
	this.buildDisplaySting = SoanPanControlPanelBuildDisplaySting;
	this.buildHexDisplaySting = SoanPanControlPanelBuildHexDisplaySting;
	this.toHex = SoanPanControlPanelToHex;
	this.display = SoanPanControlPanelDisplay;
	/* references to control panel buttons */
	this.resetBtn = document.getElementById(parent.name+"ResetBtn");
	this.animateBtn = document.getElementById(parent.name+"AnimateBtn");
	this.speedBtn = document.getElementById(parent.name+"SpeedBtn");
	this.radixChkBox = document.getElementById(parent.name+"RadixChkBox");
}

/**
 * A recursive function to build the string 
 * 'n.nnn.nnn. ... .nnn' to be displayed.
 * argument: value - an integer to be converted to string with separators.
 */
function SoanPanControlPanelBuildDisplaySting(value)
{
	if(value>=1000) 
	{  /* more than three digits - recursion */
	   var zeros=new String("000");
		 var value_str = (value%1000).toString();
		 var offset=zeros.length - value_str.length;
		 var valueString = zeros.substring(0,offset)+value_str;
		 return SoanPanControlPanelBuildDisplaySting(Math.floor(value/1000))+
		        "."+ valueString;
	}
	else
	{  /* last three digits or less - end of recursion. return digits string... */
	   return value.toString();
	}
}

/**
 * A recursive function to build the string 
 * 'n.nnn.nnn. ... .nnn' to be displayed.
 * argument: value - an integer to be converted to string with separators.
 */
function SoanPanControlPanelBuildHexDisplaySting(value)
{
	var lowNibble, highNibble, lowDigit, highDigit;
	if(value>=256) 
	{  /* more than two digits - recursion */
	   val = value%256;	 
		 var valueString = this.toHex(val);
		 return this.buildHexDisplaySting(Math.floor(value/256))+
		        ":"+ valueString;
	}
	else
	{  /* last three digits or less - end of recursion. return digits string... */
	   var valueString = this.toHex(value);
		 return valueString;
	}
}
/** 
 * Utility function to convert a 1byte value to a string of 2 Hex digits.
 * argument: value - the value to convert to Hex. 0x00 <= value <= 0xff
 * returns: the string of Hex digits.
 */

function SoanPanControlPanelToHex(value)
{  
   var HexDigits = new Array('A','B','C','D','E', 'F');
   var val = value&0xff; /* mask the bits 0-8. */
	 
	 lowNibble = (val&0x0f); /* low 4 less significant bits (0-3) nibble */
	 highNibble  = (val>>4); /* the most significant 4 bits (4-7) nibble */
	 lowDigit = lowNibble<10? lowNibble.toString():HexDigits[lowNibble-10];
	 highDigit = highNibble<10? highNibble.toString():HexDigits[highNibble-10];
	 valueString = highDigit+lowDigit;
	 return valueString;
}
/**
 * Displays the value in conrol panel text display.
 * argument: value - an integer value to be displayed.
 */
function SoanPanControlPanelDisplay(value)
{
  var displayString;
	if(this.radixChkBox.checked)
	{
	  displayString = this.buildHexDisplaySting(value);
		var offset=this.initialHexString.length - displayString.length;
  	if(offset !=0)
  	{ /* prefix value string with '0'-s ...*/
  	  displayString = this.initialHexString.substring(0,offset) + displayString;
  	}
	}
	else
	{
  	/* the less significant two digits of the 
  	value are displayed as decimals (cents) */
  	var decimals = ((value%100)<10?"0":"")+(value%100).toString(); 
  	var displayString = this.buildDisplaySting(Math.floor(value/100))+
  	                    "," + decimals;
  	var offset=this.initialString.length - displayString.length;
  	if(offset !=0)
  	{ /* prefix value string with '0'-s ...*/
  	  displayString = this.initialString.substring(0,offset) + displayString;
  	}
	}
	this.textDisplay.value = displayString; /* display */
}
/****************************************************************************/