var bitarr = [1/8388608, 1/1048576, 1/1024, 1, 1024, 1048576, 1073741824];

function omrekenen(from, to, input, output) {
  var amount = stripBad($("#"+input).val());
  var amount2 =  amount;
  amount2 = parseFloat(amount2);
  
  if (input == "pcWhat") {
      amount = eval('amount = parseFloat(' + amount + ');');
  }
  
  amount = (isNaN(amount) ? 1 : amount); 
  $("#"+input).val(amount);
  
  var fromVal = $("#" + from).val();
  var toVal = $("#" + to).val();
  var fromName = $("#"+ from +" :selected").text();
  var toName = $("#"+ to +" :selected").text();
  
  if ((fromVal == "") || (toVal == "")) {
    $("#" + output).val("");
	return;
  }
  
  if (input == "pcWhat") {
	  fromVal = bitarr[fromVal];
      toVal = bitarr[toVal];
  }
  
  if (input == "tempWhat") {
  	var v2 = get_fact(amount2, fromVal, toVal);
  } else {
 	fromVal = NewEval(eval(fromVal));
  	toVal = NewEval(eval(toVal));
  	var v2 = eval("amount * (fromVal / toVal)");
  	v2 = NewEval(v2);
  }
  
  $("#" + output).html(space(amount) + " " + fromName + " = " + space(v2) + " " + toName);
}

function get_fact(ff,from_val,to_val){
 // first convert to kelvin
 if (from_val == 0){
   ff = ff + 273.15;
 } else if (from_val == 1){
   ff = ((ff - 32)/ 1.8) + 273.15;
 } else if (from_val == 2){
   ff = ff / 1.8;
 } else if (from_val == 3){
   ff = (ff * 1.25) + 273.15;
 }

 if (ff < 0){
   // Below absolute zero
   return "Below Absolute Zero";
 }

 // now convert kelvin to unit
 if (to_val == 0){
   ff = ff - 273.15;
 } else if (to_val == 1){
   ff = (1.8 * (ff -273.15)) + 32;
 } else if (to_val == 2){
   ff = ff * 1.8;
 } else if (to_val == 3){
   ff = (ff - 273.15) / 1.25;
 }
 
 // round it off
 if (Number.prototype.toFixed) {
   ff = ff.toFixed(7);
   ff = parseFloat(ff);
 }
 else {
   var leftSide = Math.floor(ff);
   var rightSide = ff - leftSide;
   ff = leftSide + Math.round(rightSide *10000000)/10000000;
 }

 return ff;
}


function stripBad(string) {
	// If a space is next to two numbers, change to a + sign, for fractions
	// But only if number also contains a / character
	if (string.match(/\//)){
	  while (string.match(/(\d) (\d)/)){
		string = string.replace(/(\d) (\d)/, "$1\+$2");
	  }
	}

    for (var i=0, output='', valid="eE+/*-0123456789.()"; i<string.length; i++)
       if (valid.indexOf(string.charAt(i)) != -1)
          output += string.charAt(i)
    return output;
} 

function space (num)
{
	num = num + '';
	// exit if scientific notation
	if (num.indexOf('e') > -1){ return num; }

	var dec = num.indexOf('.');

	var left, right = '';
	if (dec >= 0)
	{
		left = num.substring(0, dec);
		right = num.substring(dec + 1);
	}
	else
		left = num;

	var new_left = '', new_right = '';
	for (var i = 0; i < right.length; i++)
	{
		new_right += right.charAt(i);
		if (i % 3 == 2 && i != right.length - 1)
			new_right += ' ';
	}
	for (var i = left.length - 1; i >= 0; i--)
	{
		new_left = left.charAt(i) + new_left;
		if ((left.length - 1 - i) % 3 == 2 && i != 0)
			new_left = ' ' + new_left;
	}

	return (dec >= 0) ? new_left + '.' + new_right : new_left;
}

//check whether the char code is numeric or not.
function IsCharCodeNumeric(charCode)
{
    return ((charCode > 47) && (charCode < 58));
}

function NewEval(number)
{
	if (number == undefined) return;

	var strInput = number.toString();
	
	//this is the maximum length of the input string (ignoring decimal and leading zeros) that we consider for our processing.
	//chars after this length (till the exponential part) will simply be replaced by 0.
	var maxLength = 12;
	var charCode;
	var count = 0;	
	var maxLengthIndex = 0;
	var isLeadingZero = true; 
	var currIndex = 0;

   /**********This performs steps 1 and 2 mentioned in the function comments*********/
	for(count = 0; count < strInput.length; count++)
	{
		charCode = strInput.charCodeAt(count);
		//check whether input does not contain any non numeric (0 to 9, "." and ",") characters.
		if (IsCharCodeNumeric(charCode))		
		{
			//ignore any leading zeros
			if ((charCode == 48) && !(isLeadingZero))
			{				
					currIndex++;
			}
			else if (charCode != 48)
			{				
				//if non-zero number is found, then all other following zero's are not leading zeros.
				currIndex++;
				isLeadingZero = false;
			}
		}
		//if the char is neither a "." nor "," then exit 
		else if (!((charCode == 44) || (charCode == 46)))
		{
			//we have encountered a non-numeric character (i.e. other than 0 to 9, ".", ",")
			return FormatOutPut(number);
		}
		
		//if the length has reached the maximum length that we are going to process
		//then save the index and exit the loop.
		if (currIndex == maxLength)  {maxLengthIndex = count; break;}
	}
	
	/************This performst step 3 - Retreive the exponent part *****************/
	//if number is expressed as exponential,then retreive  the exp part alone.
	//e,g, if input is 1.00000000008934e-16, then extract e-16 alone.
	var indexOfe = strInput.indexOf('e');
    var expPart = '';
	count = strInput.length-1;
	if (indexOfe != -1) 
	{	
	    for(count = strInput.length-1; count >-1; count--)
	     {
			expPart = strInput.charAt(count) + expPart;
	        if (count == indexOfe) {break;};
	     }
		count--;
	}

	/************ this performs step 4 & 5 - retreive the unwanted part and round it to zero*****************/
	//if input is 1.00000000008934e-16, then retreive 8934 and convert to 0000.
	var numberPartToIgnore = '';
	for( ;count > -1; count --)
	{
		 charCode = strInput.charCodeAt(count);
	     if (IsCharCodeNumeric(charCode))
		 {
			 numberPartToIgnore = '0' + numberPartToIgnore;
		 }
		 else 
		 {
		     numberPartToIgnore = strInput.charAt(count) + numberPartToIgnore;
		  };

	     if (count == maxLengthIndex) {break;};
	}
	count--;

	/************ this performs step 6 - round off the required part *****************/
	//round off the last digit (that we are going to process) if greater than 5 (which is char code 52)
	//if input is 1.00000000008934e-16 then convert 1.0000000000 to 1.0000000001 (as the next digit is 8 which is > 5)
	var numberPart = '';
	if (strInput.charCodeAt(maxLengthIndex)>52)
	{
		var carryOverFlag = 1;
		for (;count > -1 ; count-- )
		{
			charCode = strInput.charCodeAt(count);
			if (IsCharCodeNumeric(charCode))
			{
				charCode = charCode + carryOverFlag;
				carryOverFlag = 0;				

				//if the number is 9, then reset to 0 and set carry over flag.
				if (charCode == 58)
				{					
					charCode = 48;
					carryOverFlag = 1;
				}
				
				//add to the number 
				numberPart = String.fromCharCode(charCode) + numberPart;
			}
			else
			{
				numberPart = strInput.charAt(count) + numberPart;
			}
		}
		//now we have reached the start of the input string. And now
		//if carry over flag is set, then it means we need to prepend "1".
		if (carryOverFlag == 1)
		{
			numberPart = "1" + numberPart;
		}
	}
	else
	{
		for( ;count>-1; count--)
	    {
			numberPart = strInput.charAt(count) + numberPart;
		}
	}

	/************ validate the rounded number *****************/
	  //now we have all the required parts. 
	  var result = (numberPart + numberPartToIgnore + expPart).valueOf() * 1;
		//a;
	  //if difference between the rounded value and the original value
	  //is in the order of 1e-10, then return the rounded value. else return the original value.
  	  var diff  = Math.abs((result - number)/number); 
	  return ((diff < 1e-10) ? FormatOutPut(result): strInput);
}

/*converts 1e-16 to 1.0e-16 format */
function FormatOutPut(number)
{
	var strInput = number.toString();

	//if no exponent part found, then return the input.
	var indexOfe = strInput.indexOf('e');
	if (indexOfe == -1) return number;
	
	//find if . is present before the exponent part. if found then return the input as it is in proper format.
	var indexOfDot = strInput.substr(0, indexOfe).indexOf('.');
	if (indexOfDot > -1) return number;
	
	//include a . and 0 before the exponent part.
	var result = strInput.substr(0, indexOfe) + '.0' + strInput.substr(indexOfe, strInput.length);
	return result;	
}

var binary_numbers = new Array("0000", "0001", "0010", "0011", "0100", "0101", 
"0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111");

function toBinary(High, Low) {
	var hiHex = "ABCDEF";
	if (Low < 10 ) {
		LowNib = Low;
	} else {
		LowNib = 10 + hiHex.indexOf(Low); 
	}
	if (High  < 10 ) {
		HighNib = High;
	} else {
		HighNib = 10 + hiHex.indexOf(High);
	}
	eight_bits = binary_numbers[HighNib] + " " + binary_numbers[LowNib];
	return eight_bits;
}

function Dec2Hex(Decimal) {
	var hexChars = "0123456789ABCDEF";
	var a = Decimal % 16;
	var b = (Decimal - a)/16;
	hex = "" + hexChars.charAt(b) + hexChars.charAt(a);
	L = hexChars.charAt(a);
	H = hexChars.charAt(b);
	return hex;
}

var symbols = " !\"#$%&'()*+'-./0123456789:;<=>?@";
function toAscii ()  {
	var loAZ = "abcdefghijklmnopqrstuvwxyz";
	symbols+= loAZ.toUpperCase();
	symbols+= "[\\]^_`";
	symbols+= loAZ;
	symbols+= "{|}~";
	var loc;
	loc = symbols.indexOf($("#ascIn").val());
	if (loc >-1) { 
		Ascii_Decimal = 32 + loc;
		return (32 + loc);
    }
	return(0);  // If not in range 32-126 return ZERO
}

function getAscii(some_value) {
    $("#ascDec").val(toAscii());
	$("#ascHex").val(Dec2Hex(toAscii())); 
	$("#ascBin").val(toBinary(H, L)); 
}

function convert_roman(inputValue) {
  var num = '', i = 0, n = 0;

  while (inputValue.charAt(0) == ' ') {inputValue = inputValue.substr(1)};
  if (inputValue.indexOf(' ') != -1) {inputValue = inputValue.substr(0, inputValue.indexOf(' '))}

  if (inputValue == '') {
    alert('Er werd niets ingegeven');
	return '';
  }
  else {
    if (isNaN(inputValue)) {
      num = inputValue;
      if (num == num.toLowerCase()) {
        i = num.indexOf('u'); if (i != -1) {num = num.substr(0, i) + 'v' + num.substr(i + 1, num.length - i)};
        if (num.substr(num.length - 2, 2) == 'ij') {num = num.substr(0, num.length - 2) + 'ii'};
      }
	  n = evalRoman(num);
      if (n == -1) {
	    alert(inputValue + ' is geen geldige invoer');
		msg = '';
	  }
      else {
	    msg = n;
	  }
      }
      else {
      n = Math.round(parseFloat(inputValue));
      if (n < 1 || n > 4999) {
	    alert('Getal moet liggen tuusen 1 en 4999');
		return '';
	  }
      else {
        if (n != parseFloat(inputValue)) {alert(inputValue + ' zal worden afgerond naar ' + n)};
        msg = converts(n);
      }
    }        
  }
  return msg;
}

function evalRoman(num) {
  var i = 0, h = 0, n, t = 0, u = 0;

  num = num.toUpperCase();
  while (num.charAt(i) == 'M') {i ++};
  n = i * 1000;

  if (num.substr(i, 2) == 'CM') {h = 9; i += 2}
    else if (num.substr(i, 1) == 'D') {h = 5; i ++}
      else if (num.substr(i, 2) == 'CD') {h = 4; i += 2};
  if (h == 0 || h == 5) {while (num.charAt(i) == 'C') {h ++; i ++}};
  n += h * 100;

  if (num.substr(i, 2) == 'XC') {t = 9; i += 2}
    else if (num.substr(i, 1) == 'L') {t = 5; i ++}
      else if (num.substr(i, 2) == 'XL') {t = 4; i += 2};
  if (t == 0 || t == 5) {while (num.charAt(i) == 'X') {t ++; i ++}};
  n += t * 10;

  if (num.substr(i, 2) == 'IX') {u = 9; i += 2}
    else if (num.substr(i, 1) == 'V') {u = 5; i ++}
      else if (num.substr(i, 2) == 'IV') {u = 4; i += 2};
  if (u == 0 || u == 5) {while (num.charAt(i) == 'I') {u ++; i ++}};
  n += u;

  if (!((num == convert1000s(n) + convert100s(n) + convert10s(n) + convert1s(n))
    || (num == convert1000s(n) + convert100s(n) + convert10s(n) + convert1a(n))
    || (num == convert1000s(n) + convert100s(n) + convert10a(n) + convert1s(n))
    || (num == convert1000s(n) + convert100s(n) + convert10a(n) + convert1a(n))
    || (num == convert1000s(n) + convert100a(n) + convert10s(n) + convert1s(n))
    || (num == convert1000s(n) + convert100a(n) + convert10s(n) + convert1a(n))
    || (num == convert1000s(n) + convert100a(n) + convert10a(n) + convert1s(n))
    || (num == convert1000s(n) + convert100a(n) + convert10a(n) + convert1a(n)))) {n = -1}

  return(n);
}

function converts(n) {
  return (convert1000s(n) + convert100s(n) + convert10s(n) + convert1s(n))
}

function convert1000s(n) {
  return ('MMMM'.substr(0, (Math.floor(n / 1000))));
}

function convert100s(h) {
  var m = '', h = Math.floor((h % 1000) / 100);
  if (h == 9) {m = 'CM'}
    else if (h > 4) {m = 'DCCC'.substr(0, h - 4)}
      else if (h == 4) {m = 'CD'}
        else {m = 'CCC'.substr(0, h)};
  return m;
}

function convert100a(h) {
  var m = '', h = Math.floor((h % 1000) / 100);
  if (h > 4) {m = 'DCCCC'.substr(0, h - 4)}
    else {m = 'CCCC'.substr(0, h)};
  return m;
}

function convert10s(t) {
  var m = '', t = Math.floor((t % 100) / 10);
  if (t == 9) {m = 'XC'}
    else if (t > 4) {m = 'LXXX'.substr(0, t - 4)}
      else if (t == 4) {m = 'XL'}
        else {m = 'XXX'.substr(0, t)};
  return m;
}

function convert10a(t) {
  var m = '', t = Math.floor((t % 100) / 10);
  if (t > 4) {m = 'LXXXX'.substr(0, t - 4)}
    else {m = 'XXXX'.substr(0, t)};
  return m;
}

function convert1s(u) {
  var m = '', u = u % 10;
  if (u == 9) {m = 'IX'}
    else if (u > 4) {m = 'VIII'.substr(0, u - 4)}
      else if (u == 4) {m = 'IV'}
        else {m = 'III'.substr(0, u)};     
  return m;
}

function convert1a(u) {
  var m = '', u = u % 10;
  if (u > 4) {m = 'VIIII'.substr(0, u - 4)}
    else {m = 'IIII'.substr(0, u)};     
  return m;
}
