


function fixFields() {
	var field = this;
	var count;
	
	
    // we will test the fixing of underscores, which means we cannot fix fields
    // more than once or an error will result
	// replace all singleton underscores
	//var stringArray = field.split("");
	//field = "";
	//for (count = 0; count < stringArray.length; count++)
	//{
	//	if (stringArray[count] == "_" &&
    //        (count == 0 || stringArray[count - 1] != "_") &&
    //        (count == stringArray.length || stringArray[count + 1] != "_"))
    //        stringArray[count] = "uNdErScOrE";
    //    field += stringArray[count];
	//}
    //field =	field.replace(/_/g, "__X");  // now all two or more underscores will have __X
    //field =	field.replace(/uNdErScOrE/g, "_"); // put back singleton underscores
	
	field =	field.replace(/ /g, "__b");
	field =	field.replace(/\'/g, "__a");
	field =	field.replace(/\"/g, "__q");
	field =	field.replace(/\`/g, "__t");
	field =	field.replace(/\@/g, "__m");
	field =	field.replace(/\./g, "__d");
	field =	field.replace(/\-/g, "__u");
	field =	field.replace(/\;/g, "__s");
	field =	field.replace(/\:/g, "__c");
	field =	field.replace(/\)/g, "__p");
	field =	field.replace(/\(/g, "__P");
	field =	field.replace(/\#/g, "__3");
	field =	field.replace(/\$/g, "__4");
	field =	field.replace(/\%/g, "__5");
	field =	field.replace(/\^/g, "__6");
	field =	field.replace(/\&/g, "__7");
	field =	field.replace(/\*/g, "__8");
	field =	field.replace(/\~/g, "__0");
	field =	field.replace(/\//g, "__f");
	field =	field.replace(/\\/g, "__F");
	field =	field.replace(/\?/g, "__Q");
	field =	field.replace(/\]/g, "__e");
	field =	field.replace(/\[/g, "__E");
	field =	field.replace(/\>/g, "__g");	
	field =	field.replace(/\</g, "__G");
	field =	field.replace(/\!/g, "__B");
	field =	field.replace(/\{/g, "__W");
	field =	field.replace(/\}/g, "__w");
	field =	field.replace(/\=/g, "__C");
	field =	field.replace(/\+/g, "__A");
	field =	field.replace(/\|/g, "__I");
	field =	field.replace(/\,/g, "__M");	


        // now process non-ascii characters:


	var c = "";
	var temp = "";
	var SI = 0;
	var uchar = "";
	var newValue = "";

	for (var i=0;i<field.length;i++)
	{
	    if (i > 1000)
	       break;
	
	    u = field.charCodeAt(i);
	    temp += "  " + u;
	
	    if (u == 95 ||                // underscore
	        (u >= 65 && u <= 90) ||  // A-Z  (uppercase)
	        (u >= 97 && u <= 122) || // a-z  (lowercase)
	        (u >= 48 && u <= 57))    // 0-9
	    {
		if(SI != 0) 
		{
		    newValue += "__U" + uchar + "_";
		    SI = 0;
		    uchar = "";
		}
		newValue += String.fromCharCode(u);
	    }
	    else if( u < 128  ) // 7bits code
	    {
		if(SI != 0) 
		{
		    newValue += "__U" + uchar + "_";
		    SI = 0;
		    uchar = "";
		}
		newValue += "__U" + String.fromCharCode(u) + "_";
	    }     
	    else  // 16bits code -- Multibytes chars
	    {
	    	uchar += compress(u);
	        SI++;
	    } 
	}

	if( SI != 0 )
	{
	    newValue += "__U" + uchar + "_";
	}

        if (newValue != "")
          return newValue;
	else
	  return field;
}


var cm = new Array();
var j=0;
for (var i=71;i<=90;i++)
{
   cm[j++] = String.fromCharCode(i);
}
for (var i=97;i<=122;i++)
{
   cm[j++] = String.fromCharCode(i);
}

function compress (n)
{
  var a = Math.floor(n / (cm.length*cm.length));  //number of @cm;
  var b = Math.floor((n - (a * cm.length*cm.length))/ cm.length);
  var c = n - (a * cm.length*cm.length + b * cm.length);

  var compressed = cm[a].toString() + cm[b].toString() + cm[c].toString();
  return compressed;
}


function unfixFields() {
    var debugUnFix = false;
	var field = this;
	field =	field.replace(/__b/g, " ");
	field =	field.replace(/__a/g, "'");
	field =	field.replace(/__q/g, "\"");
	field =	field.replace(/__t/g, "`");
	field =	field.replace(/__m/g, "@");
	field =	field.replace(/__d/g, ".");
	field =	field.replace(/__u/g, "-");

	field =	field.replace(/__s/g, ";");
	field =	field.replace(/__c/g, ":");
	field =	field.replace(/__p/g, ")");
	field =	field.replace(/__P/g, "(");
	field =	field.replace(/__3/g, "#");
	field =	field.replace(/__4/g, "$");
	field =	field.replace(/__5/g, "%");
	field =	field.replace(/__6/g, "^");
	field =	field.replace(/__7/g, "&");
	field =	field.replace(/__8/g, "*");

	field =	field.replace(/__0/g, "~");
	field =	field.replace(/__f/g, "/");
	field =	field.replace(/__F/g, "\\");
	field =	field.replace(/__Q/g, "?");
	field =	field.replace(/__e/g, "]");
	field =	field.replace(/__E/g, "[");

	field =	field.replace(/__g/g, ">");
	field =	field.replace(/__G/g, "<");
	field =	field.replace(/__B/g, "!");
	field =	field.replace(/__W/g, "{");
	field =	field.replace(/__w/g, "}");
	field =	field.replace(/__C/g, "=");
	field =	field.replace(/__A/g, "+");
	field =	field.replace(/__I/g, "|");
	field =	field.replace(/__M/g, ",");



        // handle non-ascii data:



        // if the string contains Fix_Fields'd unicode chars ("__Uxxx_"), process them:
        var utf8 = field.match(/__U([\dA-F]+)_/g);
        var ucs2 = field.match(/__U([G-Za-z]+)_/g);
        
        if (debugUnFix)
            alert("field: " + field);
        
        if (ucs2 != null)
            {
                for (var i=0;i<ucs2.length;i++)
                    {
                        var regexString = ucs2[i];
                        var regex = new RegExp(regexString, "g");
                        var regexSingle = new RegExp(regexString);
                        
                        var matches = field.match(regex);
                        if (matches != null)
                            {
                                for (var j=0;j<matches.length;j++)
                                    {
                                        var noUnderscores = matches[j].slice(3,(matches[j].length-1));
                                        var replacement = unfix_ucs2(noUnderscores);
                                        if (debugUnFix)                                        
                                            {
                                                alert("field 2: " + field);

                                                alert ("regex: \"" + regexSingle.toString() + "\" noUnderscores: \"" + noUnderscores + "\"  replacement: \"" + replacement + "\"");
                                            }
                                        
                                        
                                        field = field.replace(regexSingle,replacement);
                                        
                                        
                                        //                 field = field.replace(regexSingle,"test"+j);
                                        
                                        
                                        if (debugUnFix)
                                            alert("j: " + j + "  field: " + field);
                                    }
                            }
                        if (debugUnFix)                        
                            alert("i: " + i + "  field: " + field);
                        
                    }
            }
        
        if (utf8 != null)
            {
                for (var i=0;i<utf8.length;i++)
                    {
                        var regexString = utf8[i];
                        var regex = new RegExp(regexString, "g");
                        var regexSingle = new RegExp(regexString);
                        
                        var matches = field.match(regex);
                        for (var j=0;j<matches.length;j++)
                            {
                                var noUnderscores = matches[j].slice(3,(matches[j].length-1));
                                var replacement = unfix_utf8(noUnderscores);
                                field = field.replace(regexSingle,replacement);
                            }
                    }
            }
	
	// we will test the fixing of underscores, which means we cannot fix fields
    // more than once or an error will result
	//field =	field.replace(/__X/g, "_");
	
	return field;
}


var decm = new Array ('G',0,'H',1,'I',2,'J',3,'K',4,'L',5,'M',6,'N',7,'O',8,'P',9,'Q',10,'R',11,'S',12,'T',13,'U',14,'V',15,'W',16,'X',17,'Y',18,'Z',19,'a',20,'b',21,'c',22,'d',23,'e',24,'f',25,'g',26,'h',27,'i',28,'j',29,'k',30,'l',31,'m',32,'n',33,'o',34,'p',35,'q',36,'r',37,'s',38,'t',39,'u',40,'v',41,'w',42,'x',43,'y',44,'z',45);

// what is this?
// var decm = new Array ('G',0,'H',1,'I',2,'J',3,'K',4,'L');

function getDecmValue (thisCharacter)
{
   for (var i=0;i<decm.length;i+=2)
      if (decm[i] == thisCharacter)
         return decm[i+1];
}

function unfix_ucs2 (input)
{
     var debugUcs2 = false;

	var newValue = "";
	var chars = input.split("");
        var debugNumber = "";
        var debugChars = "";
	for (var i=0;i<chars.length;i+=3)
	{
	    // 46 2116
	    var number = 2116 * getDecmValue(chars[i]) + 46 * getDecmValue(chars[i+1]) + getDecmValue(chars[i+2]);
            if (debugUcs2)
            {
                debugChars = "i: " + i + " chars[i]: " + chars[i] +  " chars[i+1]: " + chars[i+1] +  " chars[i+2]: " + chars[i+2] + "\n";
                debugChars += "i: " + i + " getDecmValue(i): " + getDecmValue(i) +  " getDecmValue(i+1): " + getDecmValue(i+1) +  " getDecmValue(i+2): " + getDecmValue(i+2) + "\n";

                debugNumber += " " + number;
                
            }
	    newValue += String.fromCharCode(number);
	}

        if (debugUcs2)
            alert ("chars: " + debugChars + "numbers: " + debugNumber);
	return newValue;
}

function unfix_utf8 (input)
{
//alert("in function unfix_utf8: " + input);
	var newValue = "";
	var chars = input.split("");
	var i = 0;
	// read all digits until we find an underscore
	var number = "";
        var lastIndex = 0;

var debug = "";

	for (var j=0;j<chars.length;j++)
	{
    	    lastIndex = j;
            var thisChar = chars[j];
debug += "  " + thisChar;

	    if (thisChar == 'A' || thisChar == 'B' || thisChar == 'C' ||
                thisChar == 'D' || thisChar == 'E' || thisChar == 'F' ||
                (thisChar <= 9 && thisChar >= 0))
	    {
		number += thisChar;
	    }
	    else if (thisChar == "_")
	    {
		i = j;
		break;
	    }
	    else
	    {
		break;
	    }
	}
//alert("chars scanned: " + debug);
	if (number != "")
	{
//alert ("number: " + number);

            if ((number.length % 2) == 1)
            {
                // If number is an odd number of chars it will go into an infinite
                // loop in the perl version of UnFix_Fields, so we don't allow it.

                newValue = "__U" + input + "_";
            }
            else
            {
                var uchar = "";
                var numbers = number.split("");
                var allValues = new Array();
                
                var temp = 0;
                for (var i=0;i<numbers.length;i+=2)  // +=2 instead of ++?
                {
                    temp++;
                    if (temp > 4)
                        break;
                    var hex = "" + numbers[i];
                    if (numbers[i+1] != null)
                        hex += "" + numbers[i+1];
                    
                    //	    	uchar += pack("H*",hex);
                    
                    var hexString = "0x" + hex;
                    var value = Number(hexString);
                    //                alert("hex = " + hex + "  value = " + value + " uchar: " + uchar);
                    uchar += String.fromCharCode(value);
                    
                    allValues[allValues.length] = value;
                    
                }
                newValue += uchar;
                //var char1 = allValues[0] + allValues[1] + allValues[2];
                //alert("char 1: " + char1);
            }
	}
	else
	{
//alert("no number!");
	    // something went wrong (no underscore?)
	    // try not to lose any characters
	    for (var thisChar=i;thisChar<=lastIndex;thisChar++)
	    {
		newValue += chars[i];
		i = lastIndex;
	    }
	}
        return newValue;
}




String.prototype.fix = fixFields;
String.prototype.unfix = unfixFields;
