// The HMM cookie 

// Given the encoding scheme, we need to ignore the most significant bit
// of each byte that is being treated as a binary field.

// We realistically have about 3KB to work with, and we should probably use 
// only one cookie. We should expect some other data to be stored in our 
// 'cookie space', and if for some reason the amount of cookies for the given
// domain runs over 20, our cookie has the potential to be discarded

// The plan is to use an encoding scheme that relies heavily on compressing 
// information into individual bits, and extracting that data with bitwise
// operators. 

// There are three different types of data we need to track: 
// 	preferences
//	progress tracking
//	favorites

// These three sections will be deliniated using the '|' character
// 
// So, we have,
//
//	PREFERENCES|PROGRESSTRACKING|FAVORITES
//
//
//	PREFERENCES:
//		In this section, we will set aside 50 bytes. The first byte
//		will be the bitwise representation of the global (not topic 
//		specific) preferences. There may be up to seven preferences,
//		each of which is either on/off or yes/no. The next
//		43 bytes each correspond to the topic-specific preferences 
// 		for a given topic. Again, we use the inner bits to specify the
//		state of the preferences
//
//	PROGRESSTRACKING:
//		This section is broken into chunks of bytes, each corresponding to
//		a given topic. Each chunk begins with a '*' character, followed 
//		by a two byte hex value that specifies the topic's ID. This is 
//		followed by 32 contiguous bytes (256 bits). Each of these 256
//		bits maps to a given page in the topic, and can be flipped on
//		when it has been completed/passed. 
//
//	FAVORITES:
//		this section is also broken into chunks of bytes, each chunk
//		corresponding to a saved favorite. Each chunk will be
//		4 bytes long. The first two bytes are a hex representation
//		of the topic ID that the page belongs to, and the next two 
//		bytes are a hex representation of the page ID within that topic.
//		We should cap the number of favorites at 100 to conserve space.
//
//
//


var hD="0123456789ABCDEF";

/**************  MODIFICATION TO HMM COOKIE 11.20.2007 **********************/
// This variable is used to find the index of the *
var star_index;  
/*************** MODIFICATION TO HMM COOKIE 11.20.2007 *********************/


// converts a decimal number to a hex number. it will pad the number with
// a leading zero to make it at least 2 bytes long
function decToHex(dec) {
	var hex = hD.substr(dec & 15 , 1);
	while(dec > 15) {dec >>= 4; hex=hD.substr(dec & 15 , 1) + hex;}
	if(hex.length == 1) { hex = "0" + hex; }
	return hex;
}

// converts a hex number to a decimal number
function hexToDec(str) {
	return parseInt(str,16);
}

/**************  MODIFICATION TO HMM COOKIE 11.20.2007 **********************/
// gets the cookie named "HMM"

function getHMMCookie() {
cookie_name = "HMM"+topicIDNum;
	return getCookie(cookie_name);
}
/**************  MODIFICATION TO HMM COOKIE 11.20.2007 **********************/

/**************  MODIFICATION TO HMM COOKIE 11.20.2007 **********************/
// sets the cookie named "HMM"
function setHMMCookie(str) {
cookie_name = "HMM"+topicIDNum;
	setCookie(cookie_name,str,10000);
}
/**************  MODIFICATION TO HMM COOKIE 11.20.2007 **********************/


// returns an array of all indices in the array arr that contain the value 
// val
function myIndicesOf(arr,val) {
	var results = new Array();
	for(var i = 0; i < arr.length; i++) {
		if(arr[i] == val) { results.push(i); }
	}
	return results;
}

// debugging tool to print out the bytes of a bit
function printBytesBits(byteValue) {
	var result = "";
	var temp = byteValue;
	for(var i = 0; i < 8; i++) {
		result = (temp & 0x1) + result;
		temp = temp >> 1;
	}
	return result;
}


// BYTE LAYOUT
//
//  MSB			 LSB
// ([0][1][2][3][4][5][6][7])
// 
// MSB is ignored! So, the largest possible byte value for us is 127

// flips on the bit at the position specified by index (remember!!! we are not
// utilizing the index 0, which is the most significant bit
function bitOn(byteValue, index) {
	switch(index) {
		case 1: return (byteValue | 64); break; 
		case 2: return (byteValue | 32); break;
		case 3: return (byteValue | 16); break;
		case 4: return (byteValue | 8); break;
		case 5: return (byteValue | 4); break;
		case 6: return (byteValue | 2); break;
		case 7: return (byteValue | 1); break;
	}
}

// flips off the bit at position specified by index (remember!!! we are not
// utilizing the index 0, which is the most significant bit
function bitOff(byteValue, index) {
	switch(index) {
		case 1: return (byteValue & (191)); break; 
		case 2: return (byteValue & (223)); break;
		case 3: return (byteValue & (239)); break;
		case 4: return (byteValue & (247)); break;
		case 5: return (byteValue & (251)); break;
		case 6: return (byteValue & (253)); break;
		case 7: return (byteValue & (254)); break;
	}
}

// grabs the bit at a given location in the byte, according to the layout above
function retrieveBit(byteValue, index) {
	switch(index) {
		case 1: return ((byteValue & 64) >> 6); break; 
		case 2: return ((byteValue & 32) >> 5); break;
		case 3: return ((byteValue & 16) >> 4); break;
		case 4: return ((byteValue & 8) >> 3); break;
		case 5: return ((byteValue & 4) >> 2); break;
		case 6: return ((byteValue & 2) >> 1); break;
		case 7: return (byteValue & 1); break;
		
	}
}


// this specifies which bit in the preference byte for a topic handles whether
// or not flash is enabled
var FLASH_PREF = 1;


// the hmmCookie class. This object is basically just a huge byte array that 
// provides functions for easy access to it's contents. 
function hmmCookie() {
	var data = new Array();
	
	this.getByte = getByte;
	this.setByte = setByte;
	this.getArray = getArray;
	this.setArray = setArray;
	this.toEncodedString = toEncodedString;
	this.getPreferenceByte = getPreferenceByte;
	this.setPreferenceByte = setPreferenceByte;
	this.setPreference = setPreference;
	this.addFavorite = addFavorite;
	this.containsFavorite = containsFavorite;
	this.getFavorite = getFavorite;
	this.removeFavorite = removeFavorite;
	this.getNumFavorites = getNumFavorites;
	this.getPageCompletion = getPageCompletion;
	this.setPageCompletion = setPageCompletion;
	this.loadEncodedString = loadEncodedString;
	this.trackPage = trackPage;
	
	// simply returns the byte array
	function getArray() {
		return data;
	}
	
	// allows you to directly assign the byte array
	function setArray(arr) {
		data = arr;
	}
	
	// returns the byte at a specified index in the array
	function getByte(index) {
		return data[index];
	}
	
	// sets a byte at the specified index in the array
	function setByte(index,value) {
		data[index] = value;
	}
	
	// given a topic number, this will return the byte containing
	// all of the preferences for that topic
	function getPreferenceByte(topicNum) {
		return data[topicNum - 1];
	}
	
	// given a topic number and a byte, this will set the preference byte
	// for that topic
	function setPreferenceByte(topicNum,byteValue) {
		data[topicNum - 1] = byteValue;
	}
	
	// pref is one of the type safe enums like, FLASH_PREF. This enum
	// specifies a particular bit in the preference byte.
	function setPreference(topicNum,pref,value) {
		var prefByte = getPreferenceByte(topicNum);
		if(value = 0) { setPreferenceByte(topicNum,bitOff(prefByte,pref)) ; }
		else { setPreferenceByte(topicNum,bitOn(prefByte,pref)) ; }
	}
	
	// given a hmmPage object, this will return the bit corresponding to whether
	// or not that page has been visited. 
	function getPageCompletion(hPage) {
		var arr = myIndicesOf(data,"*");
		var topicNum = parseInt(hPage.getTopic(),16);
		var pageNum = parseInt(hPage.getPage(),16);
	
		
		/**************  MODIFICATION TO HMM COOKIE 11.20.2007 **********************/
		com_index = star_index+pageNum;
		return data[com_index];
		/**************  MODIFICATION TO HMM COOKIE 11.20.2007 **********************/
		/**************  REMOVAL FROM HMM COOKIE 11.20.2007 **********************/
		/*var topicStart = arr[topicNum-1] + 1;
		var targetByte = data[topicStart+parseInt(pageNum / 7)];
		var offset = parseInt(pageNum % 7) + 1;
		return retrieveBit(targetByte,offset);*/
		/**************  REMOVAL FROM HMM COOKIE 11.20.2007 **********************/
		
	}
	
	// given a hmmPage object, this will turn on the bit corresponding to 
	// that page in the byte array (or off, if you set value to 0). 
	function setPageCompletion(hPage,value) {
		var arr = myIndicesOf(data,"*");
		var topicNum = parseInt(hPage.getTopic(),16);
		var pageNum = parseInt(hPage.getPage(),16);

		/**************  MODIFICATION TO HMM COOKIE 11.20.2007 **********************/
		com_index = star_index+pageNum;
		data[com_index] = 1;
		/**************  MODIFICATION TO HMM COOKIE 11.20.2007 **********************/
		/**************  REMOVAL FROM HMM COOKIE 11.20.2007 **********************/
		/*var topicStart = arr[topicNum-1] + 1;
		var targetByte = data[topicStart+parseInt(pageNum / 7)];
		var offset = parseInt(pageNum % 7) + 1;
		if(value == 0) { data[topicStart+parseInt(pageNum / 7)] = bitOff(targetByte,offset); }
		else { data[topicStart+parseInt(pageNum / 7)] = bitOn(targetByte,offset); }*/
		/**************  REMOVAL FROM HMM COOKIE 11.20.2007 **********************/
		
	}
	
	// given a hmmPage object, this will return the index into the array
	// where the favorite corresponding to that page lives. -1 if it
	// doesn't exist
	function containsFavorite(hPage) {
		var resultIndex = 0;
		var arr = myIndicesOf(data,"|");
		var index = arr[arr.length-1] + 1;
		while(index < data.length-1) {
			var topic = data[index] + (data[index+1] + "");
			var page = data[index+2] + (data[index+3] + "");
			if(topic == hPage.getTopic() && page == hPage.getPage()) {
				return resultIndex;
			}
			index += 4;
			resultIndex++;
		}
		return -1;
	}
	
	// given a hmmPage object, will create a new favorite entry in
	// the array
	function addFavorite(hPage) {
		//check to make sure that we aren't going to
		//exceed the favorite limit. 4bytes per favorite, means that 
		//we can have 100 favorites (400bytes)
		var arr = myIndicesOf(data,"|");
		if(((data.length-1) - (arr[arr.length-1])) <= 396) {
			data.push(hPage.getTopic().charAt(0));
			data.push(hPage.getTopic().charAt(1));
			data.push(hPage.getPage().charAt(0));
			data.push(hPage.getPage().charAt(1));
		}
	}
	
	// You should get the favoriteIndex from containsFavorite()
	function getFavorite(favoriteIndex) {
		var arr = myIndicesOf(data,"|");
		var index = arr[arr.length-1] + 1;
		index += (favoriteIndex * 4);
		var result = new hmmPage;
		result.setTopic(data[index] + (data[index+1] + ""));
		result.setPage(data[index+2] + (data[index+3] + ""));
		return result;
	}
	
	// removes a favorite at 'favorite Index', used in conjunction with
	// containsFavorite()
	function removeFavorite(favoriteIndex) {
		var arr = myIndicesOf(data,"|");
		var index = arr[arr.length-1] + 1;
		index += (favoriteIndex * 4);
		data.splice(index,4);
	}
	
	// returns the number of favorites currently in the array
	function getNumFavorites() {
		var arr = myIndicesOf(data,"|");
		var index = arr[arr.length-1] + 1;
		var count = 0;
		while(data[index] != null) {
			index += 4;
			count++;
		}
		return count;
	}
	
	
	// encode the contents of data as a string that is 
	// able to be placed into a cookie. We don't encode the favorites,
	// as they are simply hex digits. Hence, when we get to the favorites
	// we've passed two pipes (|), we stop doing any encoding.
	function toEncodedString() {
		var result = "";
		var pipesSeen = 0;
		for(var i = 0; i < data.length; i++) {
			if(data[i] == "|") { pipesSeen++; }
			if(isNaN(data[i]) || pipesSeen >= 2) { result += data[i]; }
		/**************  REMOVAL FROM HMM COOKIE 11.20.2007 **********************/
			//else { result += byteToChar(data[i]); }
		/**************  REMOVAL FROM HMM COOKIE 11.20.2007 **********************/
			
		/**************  MODIFICATION TO HMM COOKIE 11.20.2007 **********************/
					else { result += data[i]; }
		/**************  MODIFICATION TO HMM COOKIE 11.20.2007 **********************/
		
		}
		
		return result;
	}
	
	// pass this function the cookie that you got via getHMMCookie(), and
	// it will load up this hmmCookie object with all of the properly 
	// formatted data
	function loadEncodedString(cookieString) {
		
		var index = 0;
		// read in the first 50 preference bytes, encoding them
		// back into their byte form.
		for(var i = 0; i < 50; i++) {
			data[index] = cookieString.charAt(index);
			index++;
		}
		// place in the preferences|tracking delimeter
		data[index] = "|";
		index++;
		for(var i = 0; i < 1; i++) {
			data[index] = "*";
			star_index = index+1;
			index++;
			/**************  MODIFICATION TO HMM COOKIE 11.20.2007 **********************/
			/************* In this for loop, the limit total_pages is added ********/
			for(var j = 0; j <= total_pages; j++) {
				data[index] = cookieString.charAt(index);
				index++;
			}
			/**************  MODIFICATION TO HMM COOKIE 11.20.2007 **********************/

		}
		// place in the tracking|favorites delimiter
		data[index] = "|";
		index++;
		// now, we just read in all of the favorites bytes.
		while(index < cookieString.length) {
			data[index] = cookieString.charAt(index);
			index++;
		}
	}
	
	// call this function to track a page completion on a page. pageInfo is
	// initialized on the html page, and passed to this function on a call
	// in the header
	function trackPage(pageInfo) {
		hp = new hmmPage;
		hp.setTopic(decToHex(pageInfo["topicID"]));
		hp.setPage(decToHex(pageInfo["pageID"]));
		setPageCompletion(hp,1);
	}	
	
}

// builds a barebones default hmmCookie object.
function createDefaultHMMCookie() {
    	var defaultCk = new hmmCookie;
	var index = 0;
	for(var i = 0; i < 50; i++) {
		defaultCk.setByte(index,0);
		index++;
	}
	defaultCk.setByte(index,"|");
	index++;
	for(var i = 0; i < 1; i++) {
		defaultCk.setByte(index,"*");
		star_index = index+1;
		index++;
		
		/**************  REMOVAL FROM HMM COOKIE 11.20.2007 **********************/
		//defaultCk.setByte(index,1);
		/**************  REMOVAL FROM HMM COOKIE 11.20.2007 **********************/
		
		/**************  MODIFICATION TO HMM COOKIE 11.20.2007 **********************/
		/************* In this for loop, the limit total_pages is added ********/
		for(var j = 0; j <= total_pages; j++) {
			defaultCk.setByte(index,0);
			index++;
		}
		/**************  MODIFICATION TO HMM COOKIE 11.20.2007 **********************/
		
	}
	defaultCk.setByte(index,"|");

		/**************  MODIFICATION TO HMM COOKIE 11.20.2007 **********************/
//	alert(defaultCk);
	return defaultCk;
  	/**************  MODIFICATION TO HMM COOKIE 11.20.2007 **********************/

}

// higher level call made on the HTML pages to grab the HMM cookie and create
// a hmmCookie Object from that data. If the cookie doesn't exist, it will
// call createDefaultHMMCookie()
function grabHBSPCookie() {
	var hbspCookie = new hmmCookie;
	if(getHMMCookie() == null || getHMMCookie() == "") {
		hbspCookie = createDefaultHMMCookie();
	} else {
		hbspCookie.loadEncodedString(getHMMCookie());
	}
	return hbspCookie;	
}



// higher level byte object
function hmmByte() {
	var data = 0x0;
	this.getData = getData;
	this.setData = setData;
	this.printBits = printBits;
	
	function getData() {
		return ToChar(data);
	}
	
	function setData(d) {
		data = d;
	}
	
	function printBits() {
		var result = "";
		var temp = data;
		for(var i = 0; i < 8; i++) {
			result = (temp & 0x1) + result;
			temp = temp >> 1;
		}
		alert(result);
	}
}

// class declaration for a HMM page encoding. These are the currency that you
// pass around to most of the functions in the hmmCookie class to accurately
// specify pages. 
// topic = 2-byte topic id (in hex) 
// page = 2-byte page id (in hex) 
function hmmPage() {
	
	var topic = "XX";
	var page = "XX";
	this.getTopic = getTopic;
	this.getPage = getPage;
	this.setTopic = setTopic;
	this.setPage = setPage;
	this.toString = toString;
	
	function getTopic() {
		return topic; 
	}
	
	function getPage() {
		return page; 
	}
	
	function setTopic(t) {
		topic = t;
	}
	
	function setPage(p) {
		page = p;
	}

	function toString() {
		return topic+page;
	}
}

// These functions define a two way encoding from byte to characters and back
// these have been tested to be cookie friendly. 

function byteToChar(byteValue) {
	//return unescape(byteValue);
	switch(byteValue) {
		case 0:	return String.fromCharCode(33); break;	 
		case 1:	return String.fromCharCode(34); break;	 
		case 2:	return String.fromCharCode(35); break;	 
		case 3:	return String.fromCharCode(36); break;	 
		case 4:	return String.fromCharCode(37); break;	 
		case 5:	return String.fromCharCode(38); break;	 
		case 6:	return String.fromCharCode(39); break;	 
		case 7:	return String.fromCharCode(40); break;	 
		case 8:	return String.fromCharCode(41); break;	 
		case 9:	return String.fromCharCode(42); break;   
		case 10: return String.fromCharCode(43); break;  
 		case 11: return String.fromCharCode(44); break;  
		case 12: return String.fromCharCode(45); break;  
		case 13: return String.fromCharCode(46); break;  
		case 14: return String.fromCharCode(47); break;  
		case 15: return String.fromCharCode(48); break;  
		case 16: return String.fromCharCode(49); break;  
		case 17: return String.fromCharCode(50); break;  
		case 18: return String.fromCharCode(51); break;  
		case 19: return String.fromCharCode(52); break;  
		case 20: return String.fromCharCode(53); break;  
		case 21: return String.fromCharCode(54); break;  
		case 22: return String.fromCharCode(55); break;  
		case 23: return String.fromCharCode(56); break;  
		case 24: return String.fromCharCode(57); break;  
		case 25: return String.fromCharCode(58); break;  
		case 26: return String.fromCharCode(59); break;  
		case 27: return String.fromCharCode(60); break;  
		case 28: return String.fromCharCode(61); break;  
		case 29: return String.fromCharCode(62); break;  
		case 30: return String.fromCharCode(63); break;  
		case 31: return String.fromCharCode(64); break;  
		case 32: return String.fromCharCode(65); break;  
		case 33: return String.fromCharCode(66); break;  
		case 34: return String.fromCharCode(67); break;  
		case 35: return String.fromCharCode(68); break;  
		case 36: return String.fromCharCode(69); break;  
		case 37: return String.fromCharCode(70); break;  
		case 38: return String.fromCharCode(71); break;  
		case 39: return String.fromCharCode(72); break;  
		case 40: return String.fromCharCode(73); break;  
		case 41: return String.fromCharCode(74); break;  
		case 42: return String.fromCharCode(75); break;  
		case 43: return String.fromCharCode(76); break;  
		case 44: return String.fromCharCode(77); break;  
		case 45: return String.fromCharCode(78); break;  
		case 46: return String.fromCharCode(79); break;  
		case 47: return String.fromCharCode(80); break;  
		case 48: return String.fromCharCode(81); break;  
		case 49: return String.fromCharCode(82); break;  
		case 50: return String.fromCharCode(83); break;  
		case 51: return String.fromCharCode(84); break;  
		case 52: return String.fromCharCode(85); break;  
		case 53: return String.fromCharCode(86); break;  
		case 54: return String.fromCharCode(87); break;  
		case 55: return String.fromCharCode(88); break;  
		case 56: return String.fromCharCode(89); break;  
		case 57: return String.fromCharCode(90); break;  
		case 58: return String.fromCharCode(196); break; 
		case 59: return String.fromCharCode(92); break;  
		case 60: return String.fromCharCode(197); break; 
		case 61: return String.fromCharCode(94); break;  
		case 62: return String.fromCharCode(95); break;  
		case 63: return String.fromCharCode(96); break;  
		case 64: return String.fromCharCode(97); break;  
		case 65: return String.fromCharCode(98); break;  
		case 66: return String.fromCharCode(99); break;  
		case 67: return String.fromCharCode(100); break; 
		case 68: return String.fromCharCode(101); break; 
		case 69: return String.fromCharCode(102); break; 
		case 70: return String.fromCharCode(103); break; 
		case 71: return String.fromCharCode(104); break; 
		case 72: return String.fromCharCode(105); break; 
		case 73: return String.fromCharCode(106); break; 
		case 74: return String.fromCharCode(107); break; 
		case 75: return String.fromCharCode(108); break; 
		case 76: return String.fromCharCode(109); break; 
		case 77: return String.fromCharCode(110); break; 
		case 78: return String.fromCharCode(111); break; 
		case 79: return String.fromCharCode(112); break; 
		case 80: return String.fromCharCode(113); break; 
		case 81: return String.fromCharCode(114); break; 
		case 82: return String.fromCharCode(115); break; 
		case 83: return String.fromCharCode(116); break; 
		case 84: return String.fromCharCode(117); break; 
		case 85: return String.fromCharCode(118); break; 
		case 86: return String.fromCharCode(119); break; 
		case 87: return String.fromCharCode(120); break; 
		case 88: return String.fromCharCode(121); break; 
		case 89: return String.fromCharCode(122); break; 
		case 90: return String.fromCharCode(123); break; 
		case 91: return String.fromCharCode(124); break; 
		case 92: return String.fromCharCode(125); break; 
		case 93: return String.fromCharCode(126); break; 
		case 94: return String.fromCharCode(161); break; 
		case 95: return String.fromCharCode(162); break; 
		case 96: return String.fromCharCode(163); break; 
		case 97: return String.fromCharCode(164); break; 
		case 98: return String.fromCharCode(165); break; 
		case 99: return String.fromCharCode(166); break; 
		case 100: return String.fromCharCode(167); break;
		case 101: return String.fromCharCode(168); break;
		case 102: return String.fromCharCode(169); break;
		case 103: return String.fromCharCode(170); break;
		case 104: return String.fromCharCode(171); break;
		case 105: return String.fromCharCode(172); break;
		case 106: return String.fromCharCode(174); break;
		case 107: return String.fromCharCode(175); break;
		case 108: return String.fromCharCode(176); break;
		case 109: return String.fromCharCode(177); break;
		case 110: return String.fromCharCode(178); break;
		case 111: return String.fromCharCode(179); break;
		case 112: return String.fromCharCode(180); break;
		case 113: return String.fromCharCode(181); break;
		case 114: return String.fromCharCode(182); break;
		case 115: return String.fromCharCode(183); break;
		case 116: return String.fromCharCode(184); break;
		case 117: return String.fromCharCode(185); break;
		case 118: return String.fromCharCode(186); break;
		case 119: return String.fromCharCode(187); break;
		case 120: return String.fromCharCode(188); break;
		case 121: return String.fromCharCode(189); break;
		case 122: return String.fromCharCode(190); break;
		case 123: return String.fromCharCode(191); break;
		case 124: return String.fromCharCode(192); break;
		case 125: return String.fromCharCode(193); break;
		case 126: return String.fromCharCode(194); break;
		case 127: return String.fromCharCode(195); break;
	}	
}


function charToByte(charValue) {
	//return unescape(charValue.charCodeAt(0));
	switch(charValue.charCodeAt(0)) {
		case 33: return 0; break;    
		case 34: return 1; break;    
		case 35: return 2; break;    
		case 36: return 3; break;    
		case 37: return 4; break;    
		case 38: return 5; break;    
		case 39: return 6; break;    
		case 40: return 7; break;    
		case 41: return 8; break;    
		case 42: return 9; break;    
		case 43: return 10; break;   
		case 44: return 11; break;   
		case 45: return 12; break;   
		case 46: return 13; break;   
		case 47: return 14; break;   
		case 48: return 15; break;   
		case 49: return 16; break;   
		case 50: return 17; break;   
		case 51: return 18; break;   
		case 52: return 19; break;   
		case 53: return 20; break;   
		case 54: return 21; break;   
		case 55: return 22; break;   
		case 56: return 23; break;   
		case 57: return 24; break;   
		case 58: return 25; break;   
		case 59: return 26; break;   
		case 60: return 27; break;   
		case 61: return 28; break;   
		case 62: return 29; break;   
		case 63: return 30; break;   
		case 64: return 31; break;   
		case 65: return 32; break;   
		case 66: return 33; break;   
		case 67: return 34; break;   
		case 68: return 35; break;   
		case 69: return 36; break;   
		case 70: return 37; break;   
		case 71: return 38; break;   
		case 72: return 39; break;   
		case 73: return 40; break;   
		case 74: return 41; break;   
		case 75: return 42; break;   
		case 76: return 43; break;   
		case 77: return 44; break;   
		case 78: return 45; break;   
		case 79: return 46; break;   
		case 80: return 47; break;   
		case 81: return 48; break;   
		case 82: return 49; break;   
		case 83: return 50; break;   
		case 84: return 51; break;   
		case 85: return 52; break;   
		case 86: return 53; break;   
		case 87: return 54; break;   
		case 88: return 55; break;   
		case 89: return 56; break;   
		case 90: return 57; break;   
		case 196: return 58; break;  
		case 92: return 59; break;   
		case 197: return 60; break;  
		case 94: return 61; break;   
		case 95: return 62; break;   
		case 96: return 63; break;   
		case 97: return 64; break;   
		case 98: return 65; break;   
		case 99: return 66; break;   
		case 100: return 67; break;  
		case 101: return 68; break;  
		case 102: return 69; break;  
		case 103: return 70; break;  
		case 104: return 71; break;  
		case 105: return 72; break;  
		case 106: return 73; break;  
		case 107: return 74; break;  
		case 108: return 75; break;  
		case 109: return 76; break;  
		case 110: return 77; break;  
		case 111: return 78; break;  
		case 112: return 79; break;  
		case 113: return 80; break;  
		case 114: return 81; break;  
		case 115: return 82; break;  
		case 116: return 83; break;  
		case 117: return 84; break;  
		case 118: return 85; break;  
		case 119: return 86; break;  
		case 120: return 87; break;  
		case 121: return 88; break;  
		case 122: return 89; break;  
		case 123: return 90; break;  
		case 124: return 91; break;  
		case 125: return 92; break;  
		case 126: return 93; break;  
		case 161: return 94; break;  
		case 162: return 95; break;  
		case 163: return 96; break;  
		case 164: return 97; break;  
		case 165: return 98; break;  
		case 166: return 99; break;  
		case 167: return 100; break; 
		case 168: return 101; break; 
		case 169: return 102; break; 
		case 170: return 103; break; 
		case 171: return 104; break; 
		case 172: return 105; break; 
		case 174: return 106; break; 
		case 175: return 107; break; 
		case 176: return 108; break; 
		case 177: return 109; break; 
		case 178: return 110; break; 
		case 179: return 111; break; 
		case 180: return 112; break; 
		case 181: return 113; break; 
		case 182: return 114; break; 
		case 183: return 115; break; 
		case 184: return 116; break; 
		case 185: return 117; break; 
		case 186: return 118; break; 
		case 187: return 119; break; 
		case 188: return 120; break; 
		case 189: return 121; break; 
		case 190: return 122; break; 
		case 191: return 123; break; 
		case 192: return 124; break; 
		case 193: return 125; break; 
		case 194: return 126; break; 
		case 195: return 127; break; 
	}	
	
}



