// Author: Anthony McKale
//
// Note: modifed to javascript from orginal as2 found below
// basically identical actual to as2
//
//
// http://www.razorberry.com/blog/archives/2004/08/22/lzw-compression-methods-in-as2/
//
// A class for LZW compression modified from code posted at the following URL's
// http://www.shoe-box.org/blog/index.php/2004/05/05/13-CompressionLzw
// http://www.lalex.com/blog/comments/200405/164-compression-lzw-actionscript-2.html
//
/*
  lzwjs.js - Javascript implementation of LZW compress and decompress algorithm
  Copyright (C) 2009 Mark Lomas

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/


var lzw = {
	// Change this variable to output an xml safe string - removed this
	xmlsafe : false,
	compress : function(str){
		var dico = lzw.new_dict();
		
		var res = "";
		var txt2encode = str;
		var splitStr = txt2encode.split("");
		var len = splitStr.length;
		//256 is now the clear code
		//can be any character, but this one makes the most sense to me
		var nbChar = 257;
		var clear_code = String.fromCharCode( 256 & 0xFF) + String.fromCharCode(256 >> 8 & 0xFF);
		
		var buffer = '';	
		res += clear_code;		//start with clear code
		
		
		for (var i = 0; i <= len; i++)
		{
			var current = splitStr[i];
			
			if (dico.get(buffer + current) !== undefined)
			{
				buffer += current;
			}
			else
			{
								 
				//res += String.fromCharCode(dico[buffer]);
				//this is like pack('S',dico[buffer]);
				
				//console.log("adding %s as %s",buffer,dico.get(buffer));
				
				res += String.fromCharCode(dico.get(buffer) &
                        0xFF);
                res += String.fromCharCode(dico.get(buffer) >>
                        8 & 0xFF);
				
			
				dico.set(buffer + current,nbChar);
				
				nbChar++;
				if(nbChar > 65535)
				{
					//clear dictionary
					dico = lzw.new_dict();
					res += clear_code;
					
					nbChar = 257;
					
				}
				buffer = current;
			}
		}
		
		return res;
	},
	decompress : function (str)
	{
		//this is now broken
		var dico = lzw.new_dict();
		
		var txt2encode = str;
		var splitStr = txt2encode.split("");
		var length = splitStr.length;
		var nbChar = 256+skipnum;
		var buffer = "";
		var chaine = "";
		var result = "";
		for (var i = 0; i < length; i++)
		{
			var code = txt2encode.charCodeAt(i);
			var current = dico[code];
			if (buffer == "")
			{
				buffer = current;
				result += current;
			}
			else
			{
				if (code <= 255+skipnum)
				{
					result += current;
					chaine = buffer + current;
					dico[nbChar] = chaine;
					nbChar++;
					buffer = current;
				}
				else
				{
					chaine = dico[code];
					if (chaine == undefined) chaine = buffer + buffer.slice(0,1);
					result += chaine;
					dico[nbChar] = buffer + chaine.slice(0, 1);
					nbChar++;
					buffer = chaine;
					
				}
			}
		}
		return result;
	},
	new_dict: function()
	{
		var mydico = new Hash();
		
		for (var i = 0; i < 256; i++)
		{
			mydico.set(String.fromCharCode(i),i);
		}
		return mydico;
	}
}
