var default_text = "請輸入中文字\r\n\u8BF7\u8F93入中文字";
function txtclear() {
	document.getElementById("InputArea").value = "";
}
function clipbrdGet() {
	if (navigator.userAgent.indexOf("MSIE") >= 0) {
		if(clipboardData.getData("Text")) {
			document.getElementById("InputArea").value += clipboardData.getData("Text");
		}
		else if (document.getElementById("InputArea").value.length > 0) {
			// 不作改動
		}
		else {
			document.getElementById("InputArea").value = "請輸入文字";
		}
	}
	else {
		alert("此功能只限Internet Explorer使用");
	}
}
function clipbrdSet() {
	if (navigator.userAgent.indexOf("MSIE") >= 0) {
		if(document.getElementById("InputArea").value.length) {
			clipboardData.setData("Text", document.getElementById("InputArea").value);
		}
	}
	else {
		alert("此功能只限Internet Explorer使用");
	}
}
function supplane(num) {
	if(num >= 65536) num -= 65536;
	var num1 = Math.floor(num / 1024) + 55296;
	var num2 = num % 1024 + 56320;
	return String.fromCharCode(num1) + String.fromCharCode(num2);
}
function converte2u() {
	var content = document.getElementById("InputArea").value;
	var newStr = "";
	if(content.length == 0) {
		newStr = default_text;
	}
	else {
		content = content.replace(/&#x([\dA-Fa-f]+);/g, function(w){return "\037\036" + h2d(w.substr(3,w.length-2)) + "\037"});
		content = content.replace(/&#(\d+);/g, "\037\036$1\037");
		var col_array = content.split("\037");
		for (var i = 0; i < col_array.length; i++) {
			if(col_array[i] == 0) continue;
			if(col_array[i].substr(0,1) == "\036") {
				if(col_array[i].substr(1,col_array[i].length-1) >= 65536) {
					newStr += supplane(col_array[i].substr(1,col_array[i].length-1));
				}
				else {
					newStr += String.fromCharCode(col_array[i].substr(1,col_array[i].length-1));
				}
			}
			else newStr += col_array[i];
		}
	}
	document.getElementById("InputArea").value = newStr;
}
function converth2u() {
	var content = document.getElementById("InputArea").value;
	var newStr = "";
	if(content.length == 0) {
		newStr = default_text;
	}
	else for(var i = 0; i < content.length; i++) {
		var unicode = content.charCodeAt(i);
		var unicode2 = table2u[unicode];
		if(unicode2 > 65535) {
			newStr += supplane(unicode2);
		}
		else {
			newStr += ( unicode2 ) ? String.fromCharCode(unicode2) : String.fromCharCode(unicode);
		}
	}
	document.getElementById("InputArea").value = newStr;
}
function converts2t() {
	var content = document.getElementById("InputArea").value;
	var newStr = "";
	if(content.length == 0) {
		newStr = default_text;
	}
	else for(var i = 0; i < content.length; i++) {
		var unicode = content.charCodeAt(i);
		if(unicode >= 55296 && unicode <= 56319) {
			var unicode1 = content.charCodeAt(++i);
			if(unicode1 >= 56320 && unicode1 <= 57343) {
				unicode = 1024 * unicode - 56557568 + unicode1 - 56320;
			}
		}
		var unicode2 = table2t[unicode];
		if(unicode2 > 65535) {
			newStr += supplane(unicode2);
		}
		else if(unicode > 65535 && !unicode2) {
			newStr += supplane(unicode);
		}
		else {
			newStr += ( unicode2 ) ? String.fromCharCode(unicode2) : String.fromCharCode(unicode);
		}
	}
	document.getElementById("InputArea").value = newStr;
}
function convertt2s() {
	var content = document.getElementById("InputArea").value;
	var newStr = "";
	if(content.length == 0) {
		newStr = default_text;
	}
	else for(var i = 0; i < content.length; i++) {
		var unicode = content.charCodeAt(i);
		if(unicode >= 55296 && unicode <= 56319) {
			var unicode1 = content.charCodeAt(++i);
			if(unicode1 >= 56320 && unicode1 <= 57343) {
				unicode = 1024 * unicode - 56557568 + unicode1 - 56320;
			}
		}
		var unicode2 = table2s[unicode];
		if(unicode2 > 65535) {
			newStr += supplane(unicode2);
		}
		else if(unicode > 65535 && !unicode2) {
			newStr += supplane(unicode);
		}
		else {
			newStr += ( unicode2 ) ? String.fromCharCode(unicode2) : String.fromCharCode(unicode);
		}
	}
	document.getElementById("InputArea").value = newStr;
}
/*
  GNU通用公共許可證(GPL)
  這是一個自由軟件，任何人或機構都可以在遵守GPL守則下使用該軟件。
  原 作 者 ：亦會編程（萬碼論壇注冊 http://www.suoai.com/88988/）
  修 改 者 ：阿勤（倉頡之友。馬來西亞 http://www.chinesecj.com）丶FXAM
  版  本　 ：0.61
  瀏覽器   ：支持IE丶Netscape 及 Mozilla 最新版本
  推出日期 ：2003-7-30
  修改日期 ：2003-8-23
*/

// Gecko = Netscape 7.x & Mozilla 1.4+

LastNo=0;
SPACECHAR=" "; // 空白字元。
CandChinesePart=new Array(); //候選字，中文字部份
CandCompPart=new Array();    //候選字，後碼部份，如“我o”裡的o
AsciiStr="a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z"; //定義使用的編碼。
AsciiStr=AsciiStr.split(',');
//CodeList=CodeList.split(',');
canjiedb(); //預設用倉頡輸入法

CtrlDown=false;
CancelKey=false;

//==KeyCode 33..47
//Symbol1 = "！＂＃＄％＆＇（）＊＋，－。／";
//==KeyCode 58..64
//Symbol2 = "：；＜＝＞？＠";
//==KeyCode 91..96
//Symbol3 = "［、｝＾＿｀";
//==KeyCode 123..126
//Symbol4 = "｛｜］～";

Punct2 =  new Array('；','＝','，','－','。','／','｀');
Punct3 =  new Array('［','、','］','＇');

//==按ＳＨＩＦＴ輸出的符號
SPunct1 = new Array('）','！','＠','＃','＄','％','＾','＆','＊','（');
SPunct2 = new Array('：','＋','＜','＿','＞','？','～');
SPunct3 = new Array('｛','｜','｝','＂');

//==全形數字和字母
FullShape_No=new Array("０","１","２","３","４","５","６","７","８","９");
FullShape_BigAZ=new Array("Ａ","Ｂ","Ｃ","Ｄ","Ｅ","Ｆ","Ｇ","Ｈ","Ｉ","Ｊ","Ｋ","Ｌ","Ｍ","Ｎ","Ｏ","Ｐ","Ｑ","Ｒ","Ｓ","Ｔ", "Ｕ","Ｖ","Ｗ","Ｘ","Ｙ","Ｚ");
FullShape_SmallAZ=new Array('ａ','ｂ','ｃ','ｄ','ｅ','ｆ','ｇ','ｈ','ｉ','ｊ','ｋ','ｌ','ｍ','ｎ','ｏ','ｐ','ｑ','ｒ','ｓ','ｔ','ｕ','ｖ','ｗ','ｘ','ｙ','ｚ');

hD="0123456789ABCDEF";
function d2h(d) {
var h = hD.substr(d&15,1);
while(d>15) {d>>=4;h=hD.substr(d&15,1)+h;}
switch(h.length) {
	case 1: h = "000" + h; break;
	case 2: h = "00" + h; break;
	case 3: h = "0" + h; break;
}
return h;
}
function h2d(h) {return parseInt(h,16);}
// 二分搜索法
function FindIn(s) {
var find=-1,low=0,mid=0,high=CodeList.length;
var sEng="";
  while(low<high){
    mid=(low+high)/2;
    mid=Math.floor(mid);
    sEng=CodeList[mid];
    if(sEng.indexOf(s,0)==0){find=mid;break;}
    sEng=CodeList[mid-1];
    if(sEng.indexOf(s,0)==0){find=mid;break;}
    if(sEng<s){low=mid+1;}else{high=mid-1;}
  }
  while(find>0){
    sEng=CodeList[find-1];
    if(sEng.indexOf(s,0)==0){find--;}else{break;}
  }
  return(find);
}

function GetStr(No, s){
  var sTmp="",sChi="";
  for(i=0;i<=9;i++){
    if(No+i>=CodeList.length-1){break;}
    sTmp=CodeList[No+i];
    if(sTmp.indexOf(s)>=0){
      sChi=CodeList[No+i];
      CandCompPart[i]=sChi.substring(s.length,sChi.indexOf(SPACECHAR));
      CandChinesePart[i]=sChi.substr(sChi.lastIndexOf(SPACECHAR)+1);
      if(i<=8){document.getElementById("Cand").value+=(i+1)+"."+CandChinesePart[i]+CandCompPart[i]+'\n';}
      else{document.getElementById("Cand").value+=(0)+"."+CandChinesePart[i]+CandCompPart[i]+'';}
      LastNo=No+i;
    }else{LastNo=-1;}
  }
}

function Grep(s){
  var No=-1;
  for(i=0;i<=9;i++){CandChinesePart[i]="";}
  if(s!=""){
    No=FindIn(s);
    if(No>=0){GetStr(No, s);}
  }

  //==自動上字
  if( document.getElementById("AutoUp").checked==true && CandChinesePart[0]!="" && CandChinesePart[1]=="" && CandCompPart[0]=="" ) {
    SendCand(0);
  }
}

// 送候選字到輸入區
function SendCand(n){
  if ( n>=0 && n<=9 ) {
    SendStr(CandChinesePart[n]);
    document.getElementById("Comp").value="";
    document.getElementById("Cand").value="";
  }
}

// 設選區：暫時無用
function setSelectionRange(input, selectionStart, selectionEnd) {
  if (input.setSelectionRange) {
    input.focus();
    input.setSelectionRange(selectionStart, selectionEnd);
  } else if (input.createTextRange) {
    var range = input.createTextRange();
    range.collapse(true);
    range.moveEnd('character', selectionEnd);
    range.moveStart('character', selectionStart);
    range.select();
  }
}
// 設光標位置：暫時無用
function setCaretToEnd (input) {
  setSelectionRange(input, input.value.length, input.value.length);
}
function setCaretToBegin (input) {
  setSelectionRange(input, 0, 0);
}
function setCaretToPos (input, pos) {
  setSelectionRange(input, pos, pos);
}

// 送字串到輸入區
function SendStr(s) {
  if (s=="") { return }

  switch (browser) {
  case 1: // IE
    var r=document.selection.createRange();
    r.text=s;
    r.select(); // 不知何故，此碼可取消選區。
    break;
  case 2: // Gecko
    /*
       -simulate keypress
       *simulate scroll
       -change outputString
       -use createRange, setStart, setEnd
    */

    var obj = document.getElementById("InputArea");
    var selectionStart = obj.selectionStart;
    var selectionEnd = obj.selectionEnd;
	    var oldScrollTop = obj.scrollTop;  //因Gecko不會滾到該滾的地方。
    var oldScrollHeight = obj.scrollHeight;
    var oldLen = obj.value.length;

    obj.value = obj.value.substring(0, selectionStart) + s + obj.value.substring(selectionEnd); // 這時Gecko會將scrollTop改成0
    obj.selectionStart = obj.selectionEnd = selectionStart + s.length;
    if (obj.value.length == oldLen) { // 如果用戶在後面輸入，就直接滾到後面。
      obj.scrollTop = obj.scrollHeight;
    } else if (obj.scrollHeight > oldScrollHeight) { // 如果TextArea增加了高度，就滾下一點點
      obj.scrollTop = oldScrollTop + obj.scrollHeight - oldScrollHeight;
    } else { // 其它情形就滾回之前的地方
      obj.scrollTop = oldScrollTop;
    }
    break;
  default: // 其它，就在後面加字算了
    document.getElementById("InputArea").value += s;
  }
}

// 將半形字母換成全形字母
function ToFullShapeLetter(aStr) {
  var s="";

  for (i=0;i<aStr.length;i++) {
    var c = aStr.charCodeAt(i);
    if (c>=65 && c<=90) {
      s += FullShape_BigAZ[c-65];
    } else if (c>=97 && c<=122) {
      s += FullShape_SmallAZ[c-97];
    } else {
      s += aStr.charAt(i);
    }
  }

  return s;
}

function ImeKeyDown(e) {
  var s="";
  var key = e.which ? e.which : e.keyCode;

  CtrlDown=false;

  switch (key) {
  //==Backspace
  case 8:
    if (document.getElementById("Comp").value!="") {
      s=document.getElementById("Comp").value;
      document.getElementById("Comp").value = s.substr(0, s.length-1);
      document.getElementById("Cand").value = "";
      Grep(document.getElementById("Comp").value);
      //TODO: how to cancel KeyDown in Opera 7.11? Hack it?
      CancelKey = true;
      return (false);
    }
    return (true);

  //==Tab
  case 9:
    SendStr('　');
    CancelKey = true;
    return (false);

  //==Esc
  case 27:
    document.getElementById("Comp").value="";
    document.getElementById("Cand").value="";
    CancelKey = true;
    return (false); //Esc會把全部文字刪除，故禁止 Esc鍵 起任何作用。

  //==PageUp
  case 33:
  case 57383: // Opera 7.11
    s=document.getElementById("Comp").value;
    if (s!="") {
      document.getElementById("Cand").value="";
      if((LastNo-19)>FindIn(s)){
        LastNo=LastNo-19;GetStr(LastNo, s);
      } else {
        GetStr(FindIn(s), s);
      }
      CancelKey = true;
      return(false);
    }
    return(true);

  //==PageDown
  case 34:
  case 57384: // Opera 7.11
    s=document.getElementById("Comp").value;
    if ( s!="" && LastNo!=-1 ) {
      document.getElementById("Cand").value="";
      GetStr(LastNo+1, s);
      CancelKey = true;
      return(false);
    }
    return(true);

  //==Space
  case 32:
    if(document.getElementById("Comp").value!="") {
      //TODO: sound if nothing in Cand
      SendCand(0);
      CancelKey = true;
      return(false);
    }
    return(true);

  //==Enter
  case 13:
    if (document.getElementById("Comp").value!="") {
      SendStr( document.getElementById("FullShape").checked ?
        ToFullShapeLetter(document.getElementById("Comp").value) :
        document.getElementById("Comp").value);
      document.getElementById("Comp").value="";
      document.getElementById("Cand").value="";
      CancelKey = true;
      return(false);
    }
    return(true);

  //==F9
  case 120:
  case 57353: // Opera 7.11
    CtrlDown=true;
    break;
  //==F12
  case 123:
  case 57356: // Opera 7.11
    document.getElementById("FullShape").checked = !document.getElementById("FullShape").checked;
    CancelKey = true;
    return (false);

  //==Ctrl
  case 17:
  case 57402: // Opera 7.11
//  CtrlDown=true; // disable
    break;
  }

  if (e.ctrlKey) { return (true) };

  //==數字和符號
  if (key>=48 && key<=57) {
    if (e.shiftKey) { // 0-9????
      if (document.getElementById("FullShape").checked || document.getElementById("EnglishMode").checked) {
        SendStr(SPunct1[key-48]);
        CancelKey = true;
        return (false);
      }
    } else { // ??
      if (document.getElementById("Comp").value=="") {
        if (document.getElementById("FullShape").checked || document.getElementById("EnglishMode").checked) {
          SendStr(FullShape_No[key-48]);
          CancelKey = true;
          return (false);
        }
      } else {
        if (document.getElementById("EnglishMode").checked) {
          SendCand( key==48 ? 9 : (key-49) );
          CancelKey = true;
          return (false);
        }
      }
    }
    return (true);
  }
  //==其它符號
  if (document.getElementById("FullShape").checked || document.getElementById("EnglishMode").checked) {
    if (key>=186 && key<=192) {
      SendStr( e.shiftKey ? SPunct2[key-186] : Punct2[key-186] );
      CancelKey = true;
      return (false);
    }
    if (key>=219 && key<=222) {
      SendStr( e.shiftKey ? SPunct3[key-219] : Punct3[key-219] );
      CancelKey = true;
      return (false);
    }
  }

  if (browser==2) {
    if (document.getElementById("FullShape").checked || document.getElementById("EnglishMode").checked) {
      switch (key) {
      case 59: // "Gecko 之分號和冒號" 的 keyCode 是 59
        SendStr( e.shiftKey ? SPunct2[0] : Punct2[0] );
        CancelKey = true;
        return (false);
      case 61:
        SendStr( e.shiftKey ? SPunct2[1] : Punct2[1] );
        CancelKey = true;
        return (false);
      case 109:
        SendStr( e.shiftKey ? SPunct2[3] : Punct2[3] );
        CancelKey = true;
        return (false);
      }
    }
  }

  return(true);
}

function ImeKeyPress(e) {
  var key = e.which ? e.which : e.keyCode;
  // Gecko 雖不能於 OnKeyDown 取消鍵，但它卻是在 OnKeyPress 之後才執行鍵的動作，故於 OnKeyPress 取消鍵亦無所謂。
  // 但 Opera 在 OnKeyPress 之前已執行鍵的動作，故仍未能取消 Backspace 等鍵。
  // 為什麼不連IE也在此取消多一次？即在OnKeyDown取消，在OnKeyPress再取消。因會出現一個問題：快速輸入文字時，第一個字會被取消。原因未知。
  if (browser==2 || browser==3) {
    if (CancelKey) {
      CancelKey = false;
      return (false);
    }
  }

  if (e.ctrlKey) { return (true); }

  // 為何不將A-Z的處理放在OnKeyDown ? 因無從知道Caps Lock的狀況。
  //==A-Z
  if ( key>=65 && key<=90 ) {
    if (document.getElementById("FullShape").checked) {
      SendStr(FullShape_BigAZ[key-65]);
      return (false);
    }
    return (true);
  }

  //==a-z
  if (key>=97 && key<=122) {
	    if (!document.getElementById("EnglishMode").checked) {
      if (document.getElementById("FullShape").checked) {
        SendStr( FullShape_SmallAZ[key-97] );
        return (false);
      }
      return (true);
    } else {
      s=document.getElementById("Comp").value;
      if (s.length<MAX) {
        document.getElementById("Comp").value+=AsciiStr[key-97];
        document.getElementById("Cand").value="";
        Grep(document.getElementById("Comp").value);
      }
      return (false);
    }
  }

  // Gecko 的某些鍵會產生兩個KeyCode，如?和/，須取消其中一個，否則將一鍵兩字
  if (browser==2) {
    switch (key) {
    case 47: case 63:
      if (document.getElementById("EnglishMode").checked || document.getElementById("FullShape").checked) {
        return (false);
      }
      break;
    }
  }
  return (true);
}

function ImeKeyUp(e) {
  var key = e.which ? e.which : e.keyCode;

  //==Ctrl
  if (key==17 || key==57402) {
    if (CtrlDown==true) {
      document.getElementById("EnglishMode").checked = !document.getElementById("EnglishMode").checked;
    }
  }
  //==F9
  if (key==120 || key==57353) {
    if (CtrlDown==true) {
      document.getElementById("EnglishMode").checked = !document.getElementById("EnglishMode").checked;
    document.getElementById("Comp").value="";
    document.getElementById("Cand").value="";
    CancelKey = true;
    }
  }
  // 秀出Unicode
  if (1) {
    var obj = document.getElementById("InputArea");
    if(browser!=2 && document.selection ){
	// The current selection
		var range = document.selection.createRange();
	// We'll use this as a 'dummy'
		var stored_range = range.duplicate();
	// Select all text
		stored_range.moveToElementText(obj);
	// Now move 'dummy' end point to end point of original range
		stored_range.setEndPoint( 'StartToStart', range );
	// Now we can calculate start and end points
		obj.selectionStart = obj.value.length - stored_range.text.length + range.text.length;
		obj.selectionEnd = obj.selectionStart + range.text.length;
    }
    var selectionStart = obj.selectionStart;
    var selectionEnd = obj.selectionEnd;
	var unicode = obj.value.substring(selectionStart, selectionStart+1).charCodeAt(0);
	document.getElementById("Cinfo").value=d2h(unicode);
	if(unicode >= 55296 && unicode <= 56319) {
		var unicode2 = obj.value.substring(selectionStart+1, selectionStart+2).charCodeAt(0);
		if(unicode2 >= 56320 && unicode2 <= 57343) {
			document.getElementById("Cinfo").value=d2h(1024*unicode-56557568+unicode2-56320);
		}
	}
	var unicodeexplanation = arrayline[h2d(document.getElementById("Cinfo").value)];
	if(h2d(document.getElementById("Cinfo").value) >= 13312 && h2d(document.getElementById("Cinfo").value) <= 19893 || h2d(document.getElementById("Cinfo").value) >= 19968 && h2d(document.getElementById("Cinfo").value) <= 40899 || h2d(document.getElementById("Cinfo").value) >= 131072 && h2d(document.getElementById("Cinfo").value) <= 173791 || h2d(document.getElementById("Cinfo").value) >= 173824 && h2d(document.getElementById("Cinfo").value) <= 177972)
		unicodeexplanation = "CJK UNIFIED IDEOGRAPH";
	document.getElementById("Cinfo").value = "U+" + document.getElementById("Cinfo").value + " " + unicodeexplanation;
  }
  return(true);
}
