// #################################################################################
// #	File Name	: KanjiCross1.js
// #	Project		: KanjiCross
// #	System		: JLP-TEST LEVEL 1 & 2
// #	Purpose		: Generates KANJI CrossWord Table
// #	Function	: (eg.) mu2iafControl
// #	Medel		: (eg.) This program is based on the Document Object Model (DOM)
// #	Language	: JavaScript (Client Side Scripting. ver: 5.x)
// #	Include		: (eg.) ie.js, ie6.js
// #	Date Issued	: 2007/01/13(Sat)-17:49:13
// #	Base URL	: http://www.all.co.nz/
// #	Location	: js/
// #	Usage		:
// #	Browsers	: (eg.) IE5.x and above
// #	Requirement	: (eg.) <BODY ID='oBody'>
// #	Restriction	: (eg.) inline style only
// #	Author		: Hiroto Sekine (Able LL Systems Dpt. CHC, NZL)
// #	Copyright	: (C) 2007 Southern Cross Virtual Co., Ltd. All Rights Reserved.
// #	Contact		: info@all.co.nz
// #	Tab Stop	: 4 (Suitable TAB stop size to view this Source Code)
// # ===============================================================================
// #	** Revision **
// # Date	Description												Sign	  Mark
// # ------+-------------------------------------------------------+---------+------
// #
// #################################################################################
@set @DEBUG = 0	// Program Debug Flag: ON(>=1)/OFF(=0)/(==9)Test Release Mode
// ###########################################################################
// #                            << NOTICE >>                                 #
// # THIS PROGRAM CODE BELONGS TO SOUTHERN CROSS VIRTUAL CO., LTD. IT IS     #
// # CONSIDERED A TRADE SECRET AND IS NOT TO BE DIVULUGED OR USED BY PARTIES #
// # WHO HAVE NOT RECEIVED WRITTEN AUTHORIZATION FROM THE OWNER.             #
// # ----------------------------------------------------------------------- #
// #                            << 通  知 >>                                 #
// # 本プログラムはSOUTHERN CROSS VIRTUAL CO., LTD.の財産です。本プログラム  #
// # はトレード・シークレットとみなされ、当該権利者の書面による許可なくして、#
// # 漏洩または使用を禁じます。                                              #
// ###########################################################################

var	F = document.all;
var lastSelection = null;
var gbCompleteTableB = false;
var gbCompleteTableC = false;
var	nSwaps = 0;
var	bFirstSwap = false;
var	oSaveCurrentObject = null;
var MSG0 = "";
var TIP0 = "";

var	MIN_ROWS	=  1;	// Min Rows
var	MIN_COLS	=  1;	// Min Cols
var	MAX_ROWS	=  7;	// Crossword Table Rows
var	MAX_COLS	=  7;	// Crossword Table Cols
var	MAX_LIST	=  3;	// KANJI List Column Num
var	ANS_CELL	=  4;	// Answer Kanji Idiom size
var	IMG_SIZE	= 49;	// KANJI Image Pic Size (px)
var	EXT_CELL	=  2;	// Extra Cell for KANJI LIST
var	SPS_CELL	= 13;	// Space Cells
var	NET_CELL	= (MAX_ROWS*MAX_COLS)-SPS_CELL;

var	sDATE_CLASS_ID		= "MDATE2";
var	sKCROSSWORD_TABLE	= "oKanjiCrosTable";
var	sADDLIST_TABLE		= "oKanjiAddTable";
var	sANSLIST_TABLE		= "oKanjiAnsTable";
var	sPRINT_CROSTABLE	= "printcross1.htm";

var	CELL_TYPD	= "D";
var	CELL_TYPR	= "R";
var	CELL_TYPS	= "S";
var	NO_WIDTH	= 2;	// Image File body name size: i.e 00.jpg "00" is 2
var	INIT_TIMES	= "00:00:00:000";

var	KANJI_MAX_NUM = (MAX_ROWS * MAX_COLS) + EXT_CELL;
var	K_WIDTH		= IMG_SIZE*3;
var	K_HEIGHT	= IMG_SIZE*3;
var	K_IMGNO_0	= 0;
var	K_CTYPE_1	= 1;
var	K_LFACE_2	= 2;
var	K_STROK_3	= 3;
var	K_CMEAN_4	= 4;
var	K_OREAD_5	= 5;
var	K_KREAD_6	= 6;
var	K_ALREC_7	= -1;

function aPak(a, b){
	this.No  = a;	// Cell SEQ no: 0, 1, 2,...
	this.Chr = b;	// Correct Char
}
function makeAnswer(){
	var i=0;
	this[i++] = new aPak(  1, "0101");
	this[i++] = new aPak(  6, "0606");
	this[i++] = new aPak( 32, "3232");
	this[i++] = new aPak( 42, "4242");
	this.length = i;
}
var	AnsArray = new makeAnswer();
var	ANSCODE  = new Array( "01", "42", "32", "06" );
var	SP		 = "　";
var	OPNIMG	 = "<img src='";
var	CLSIMG	 = "' />";
var	DATADIR	 = "kanj/";
var	DATAEXT	 = ".jpg";
var	IMG_TAG	 = "<IMG";

var	DATA_CELL_COLOR	= "white";
var	FIXD_CELL_COLOR	= "black";
var	SPEC_CELL_COLOR	= "black";

function WinMsg( sMsg ){
	window.alert( sMsg );
}
function kPak(a, b, c, d, e, f, g){
	this.oKanji = new Array(7);
	this.oKanji[0] = a;	// Kanji Pic
	this.oKanji[1] = b;	// Cell Type (D:Data, S:Space, or R:Reserved)
	this.oKanji[2] = c;	// Kanji Character(string data)
	this.oKanji[3] = d;	// Kanji stroke number
	this.oKanji[4] = e;	// Kanji core meaning
	this.oKanji[5] = f;	// Kanji 音読み
	this.oKanji[6] = g;	// Kanji 訓読み
}
function makeKanjiData(){
	var	i = 0;
	this[i++] = new kPak( "00", "R", "十",  2,	"TEN",	"ジュウ",	"とお" );
	this[i++] = new kPak( "01", "D", "年",  6,	"YEAR",	"ネン",	"とし" );
	this[i++] = new kPak( "02", "D", "一",  1,	"ONE",	"イチ",		"ひと(つ)" );
	this[i++] = new kPak( "03", "D", "日",  4,	"DAY",	"ニチ/ジツ","ひ" );
	this[i++] = new kPak( "04", "S",  SP ,  0,	"",	"",	"" );
	this[i++] = new kPak( "05", "R", "食",  9,	"EAT/FOOD",	"ショク",	"たべ(る)" );
	this[i++] = new kPak( "06", "D", "事",  8,	"AFFAIR",	"ジ",	"こと" );
	this[i++] = new kPak( "07", "S",  SP ,  0,	"",	"",	"" );
	this[i++] = new kPak( "08", "R", "代",  5,	"SUBSTITUTE/CHARGE",	"ダイ",	"か(える)" );
	this[i++] = new kPak( "09", "S",  SP ,  0,	"",	"",	"" );
	this[i++] = new kPak( "10", "R", "光",  6,	"RAY",	"コウ",	"ひかり" );
	this[i++] = new kPak( "11", "D", "学",  8,	"STUDY",	"ガク",	"まな(ぶ)" );
	this[i++] = new kPak( "12", "S",  SP ,  0,	"",	"",	"" );
	this[i++] = new kPak( "13", "R", "務", 11,	"DUTY",	"ム",	"つと(める)" );
	this[i++] = new kPak( "14", "D", "静", 14,	"QUIET/STATIC",	"セイ",	"しず(か)" );
	this[i++] = new kPak( "15", "D", "物",  8,	"THING/OBJECT",	"ブツ",	"もの" );
	this[i++] = new kPak( "16", "R", "画",  8,	"DRAW",	"ガ",	"かく" );
	this[i++] = new kPak( "17", "S",  SP ,  0,	"",	"",	"" );
	this[i++] = new kPak( "18", "R", "派",  9,	"SECT",	"ハ",	"(NIL)" );
	this[i++] = new kPak( "19", "D", "出",  5,	"GO OUT",	"シュツ",	"で(る)" );
	this[i++] = new kPak( "20", "D", "所",  8,	"PLACE",	"ショ",	"ところ" );
	this[i++] = new kPak( "21", "R", "電", 13,	"ELECTRICITY",	"デン",	"(NIL)" );
	this[i++] = new kPak( "22", "S",  SP ,  0,	"",	"",	"" );
	this[i++] = new kPak( "23", "D", "廊", 12,	"HALLWAY",	"ロウ",	"(NIL)" );
	this[i++] = new kPak( "24", "R", "下",  3,	"DOWN",	"カ/ゲ",	"した" );
	this[i++] = new kPak( "25", "S",  SP ,  0,	"",	"",	"" );
	this[i++] = new kPak( "26", "R", "世",  5,	"WORLD",	"セ",	"よ" );
	this[i++] = new kPak( "27", "S",  SP ,  0,	"",	"",	"" );
	this[i++] = new kPak( "28", "D", "気",  6,	"GAS/SPRIT",	"キ/ケ",	"(NIL)" );
	this[i++] = new kPak( "29", "R", "道", 12,	"WAY/ROAD",	"ドウ",	"みち" );
	this[i++] = new kPak( "30", "S",  SP ,  0,	"",	"",	"" );
	this[i++] = new kPak( "31", "D", "流", 10,	"FLOW",	"リュウ",	"なが(れ)" );
	this[i++] = new kPak( "32", "D", "行",  6,	"GO",	"コウ/ギョウ",	"い(く)" );
	this[i++] = new kPak( "33", "D", "作",  7,	"MAKE",	"サク",	"つく(る)" );
	this[i++] = new kPak( "34", "D", "家", 10,	"HOUSE/HOME",	"カ/ヤ",	"いえ/うち" );
	this[i++] = new kPak( "35", "S",  SP ,  0,	"",	"",	"" );
	this[i++] = new kPak( "36", "D", "義", 13,	"GOOD",	"ギ",	"よし" );
	this[i++] = new kPak( "37", "R", "軍",  9,	"ARMY",	"グン",	"(NIL)" );
	this[i++] = new kPak( "38", "S",  SP ,  0,	"",	"",	"" );
	this[i++] = new kPak( "39", "R", "政",  9,	"POLITICAL", "セイ", "まつりごと" );
	this[i++] = new kPak( "40", "S",  SP ,  0,	"",	"",	"" );
	this[i++] = new kPak( "41", "R", "庭", 10,	"GARDEN",	"テイ",	"にわ" );
	this[i++] = new kPak( "42", "D", "中",  4,	"MIDDLE",	"チュウ",	"なか" );
	this[i++] = new kPak( "43", "R", "心",  4,	"HEART/CENTER",	"シン",	"こころ" );
	this[i++] = new kPak( "44", "D", "人",  2,	"HUMAN BEING",	"ジン/ニン","ひと" );
	this[i++] = new kPak( "45", "R", "物",  8,	"THING/OBJECT",	"ブツ",	"もの" );
	this[i++] = new kPak( "46", "S",  SP ,  0,	"",	"",	"" );
	this[i++] = new kPak( "47", "R", "歯", 12,	"TEETH",	"シ",	"は" );
	this[i++] = new kPak( "48", "D", "科",  9,	"SUBJECT",	"カ",	"しな" );
	this[i++] = new kPak( "49", "D", "動", 11,	"MOVE",	"ドウ",	"うご(く)" );
	this[i++] = new kPak( "50", "D", "植", 12,	"PLANT",	"ショク",	"うえ(る)" );
	this.length = i;
}
var	KANJI = new makeKanjiData();
function fnGetKanjifaceByImgNo( baseData, idx1, idx2 ){
	if (typeof(KANJI) != "object") return("???");
	for (var i=0; i<KANJI.length; i++){
		if (KANJI[i].oKanji[idx1] == baseData) return((idx2 == -1) ? KANJI[i] : KANJI[i].oKanji[idx2]);
	}
	return("???");
}
function showTime(){
//   var d, s = "現在の世界協定時刻 (UTC): ";
//   var c = ":";
//   d = new Date();
//   s += d.getUTCHours() + c;
//   s += d.getUTCMinutes() + c;
//   s += d.getUTCSeconds() + c;
//   s += d.getUTCMilliseconds();
      var d, tz, s = "現在のローカル時間は、グリニッジ標準時 (GMT) より";
   d = new Date();
   alert(d.toUTCString());

   tz = d.getTimezoneOffset();
   if (tz < 0)
      s += tz / 60 + " 時間前です。";
   else if (tz == 0)
      s += "GMT";
   else
      s += tz / 60 + " 時間後です。";

   WinMsg(s);

}
function fnPrintCrossWordBoard(){
	window.open(sPRINT_CROSTABLE, "", "width=650, height=550");
}
function fnCreateGuideTables(){
	var	oRow, oCell, iRow, iCol, iChrCode;
	var	sChrCode = new Array( "A", "B", "C", "D", "E", "F", "G" );

	with(document){
		var	oDiv   = createElement( "DIV" );
		var	oTbody = createElement( "TBODY" );
		var	oTable = createElement( "TABLE" );
	}
	for (iRow=0; iRow<MIN_ROWS; iRow++){
		oRow = document.createElement( "TR" );
		for (iCol=0; iCol<MAX_COLS; iCol++){
			oCell = document.createElement( "TD" );
			oCell.innerText = sChrCode[iCol];
			with(oCell.style){
				posWidth 	  = 53;
				textAlign 	  = "center";
				verticalAlign = "bottom";
				height 		  = 25;
			}
			oRow.appendChild( oCell );
		}
	}
	oTbody.appendChild( oRow );
	oTable.appendChild( oTbody );
	with(oTable){
		border = 0;
		padding = 2;
		style.borderStyle = "none";
		style.fontFamily  = "Times New Roman";
		style.fontWeight  = "bold";
	}
	oDiv.appendChild( oTable );
	with(oDiv.style){
		position = "absolute";
		posTop 	 = 30;
		posLeft  = 48;
		display  = "none";
	}
	oDiv.id = "oTopGuide";
	oBody.appendChild( oDiv );

	with(document){
		oDiv   = createElement( "DIV" );
		oTbody = createElement( "TBODY" );
		oTable = createElement( "TABLE" );
	}
	for (iRow=0; iRow<MAX_ROWS; iRow++){
		oRow = document.createElement( "TR" );
		for (iCol=0; iCol<MIN_COLS; iCol++){
			oCell = document.createElement( "TD" );
			oCell.innerText = iRow + 1;
			with(oCell.style){
				posWidth 	  = 15;
				textAlign 	  = "right";
				verticalAlign = "middle";
				height 		  = 55;
			}
			oRow.appendChild( oCell );
		}
		oTbody.appendChild( oRow );
	}
	oTable.appendChild( oTbody );
	with(oTable){
		border = 0;
		padding = 2;
		style.borderStyle = "none";
		style.fontFamily  = "Times New Roman";
		style.fontWeight  = "bold";
	}
	oDiv.appendChild( oTable );
	with(oDiv.style){
		position = "absolute";
		posTop   = 64;
		posLeft  = 20;
		display  = "none";
	}
	oDiv.id = "oLeftGuide";
	oBody.appendChild( oDiv );
}
function fnCreateAnsTable(sTableID, iRowNum, iColNum){
	var	oTable = F[ sTableID ];
	if (oTable == null){
		WinMsg( "Table Container '" +  sTableID + "' is not found in the MHTL file.");
		return false;
	}
	var	oRow;
	var	oCell;
	var	iRow, iCol;
	var	q = 0;
	var	oKanjiTable = document.createElement( "TABLE" );
	var	oTbody = document.createElement( "TBODY" );
	with(oKanjiTable.style){
		borderWidth = "2px";
		borderColor = "MidnightBlue";
		borderStyle = "solid";
		padding     = "1px";
	}
	for (iRow = 0; iRow < iRowNum; iRow++){
		oRow = document.createElement( "TR" );
	    for (iCol = 0; iCol < iColNum; iCol++){
		  	oCell = document.createElement( "TD" );
			oCell.innerHTML = OPNIMG + DATADIR + AnsArray[iCol].Chr.substr(0, 2) + DATAEXT + CLSIMG;
			with(oCell.style){
				borderWidth = "1px";
				borderColor = "DarkRed";
				borderStyle = "solid";
				padding     = "1px";
			}
		  	oRow.appendChild( oCell );
	    }
	    oTbody.appendChild( oRow );
	}
	oKanjiTable.appendChild( oTbody );
	oKanjiTable.id = "oTableB";
	oKanjiTable.onclick = onclickCell;
	oTable.appendChild(oKanjiTable);
	oTable.style.display = "none";
}
function fnCreateAddTable(sTableID, iRowNum, iColNum){
	var	oTable = F[ sTableID ];
	if (oTable == null){
		WinMsg( "Table Container '" +  sTableID + "' is not found in the MHTL file.");
		return false;
	}
	var	oRow;
	var	oCell;
	var	iRow, iCol;
	var	i, j;
	var	sFileNo;
	var	Loop = KANJI.length-EXT_CELL;
	var	DataArray = new Array(MAX_LIST * MAX_ROWS);
	for (i=0, j=0; i<Loop; i++){
		if (KANJI[i].oKanji[1] == CELL_TYPD){
			DataArray[j++] = KANJI[i].oKanji[0];
		}
	}
	DataArray[j++] = "49";
	DataArray[j++] = "50";	// j should be 21

  	var nIndex, nRnd, arrCount, bFound;

  var arr = new Array(j);
  for (nIndex = 0; nIndex < j; nIndex++){
    bFound = true;
    while (bFound){
      bFound = false;
      nRnd = getRandom(j-1);
      for (arrCount = nIndex; arrCount >= 0; arrCount--) {
        if (arr[arrCount] == DataArray[nRnd]){
          bFound = true;  // Oops!  Found it, try again.
          break;
        }
      }
    }
    arr[nIndex] = DataArray[nRnd];
  }
	var p = 0;
	var	oKanjiTable = document.createElement( "TABLE" );
	var	oTbody = document.createElement( "TBODY" );
	with(oKanjiTable.style){
		borderWidth = "2px";
		borderColor = "MidnightBlue";
		borderStyle = "solid";
		padding     = "1px";
	}
	for (iRow = 0; iRow < iRowNum; iRow++){
		oRow = document.createElement( "TR" );
	    for (iCol = 0; iCol < iColNum; iCol++){
		  	oCell = document.createElement( "TD" );
			oCell.innerHTML = OPNIMG + DATADIR + arr[p++] + DATAEXT + CLSIMG;
			with(oCell.style){
				borderWidth = "1px";
				borderColor = "MidnightBlue";
				borderStyle = "solid";
				padding     = "1px";
			}
		  	oRow.appendChild( oCell );
	    }
	    oTbody.appendChild( oRow );
	}
	oKanjiTable.appendChild( oTbody );
	oKanjiTable.id = "oTableA";
	oKanjiTable.onclick = onclickCell;
	oTable.appendChild(oKanjiTable);
}
function fnCreateCrossTable(sTableID, iRowNum, iColNum){
	var	oTable = F[ sTableID ];
	if (oTable == null){
		WinMsg( "Table Container '" +  sTableID + "' is not found in the MHTL file.");
		return false;
	}
	var	oRow;
	var	oCell;
	var	iRow, iCol;
	var p = 0;
	var	oKanjiTable = document.createElement( "TABLE" );
	var	oTbody = document.createElement( "TBODY" );
	with(oKanjiTable.style){
		borderWidth = "2px";
		borderColor = "LightSeaGreen";
		borderStyle = "solid";
		padding     = "1px";
	}
	for (iRow = 0; iRow < iRowNum; iRow++){
		oRow = document.createElement( "TR" );
	    for (iCol = 0; iCol < iColNum; iCol++){
		  	oCell = document.createElement( "TD" );
		  	switch(KANJI[p].oKanji[1]){
				default:
				case CELL_TYPD :
					with(oCell){
						innerHTML = SP;
						style.backgroundColor = DATA_CELL_COLOR;
					}
					break;

				case CELL_TYPR :
					with(oCell){
						innerHTML = OPNIMG + DATADIR + KANJI[p].oKanji[0] + DATAEXT + CLSIMG;
						className = "fixed";
						style.backgroundColor = FIXD_CELL_COLOR;
					}
					break;

				case CELL_TYPS :
					with(oCell){
						innerHTML = SP;
						style.backgroundColor = SPEC_CELL_COLOR;
					}
			}
			with(oCell.style){
				borderWidth = "1px";
				borderColor = "LightSeaGreen";
				borderStyle = "solid";
				padding     = "1px";
			}
			p++;
		  	oRow.appendChild( oCell );
	    }
	    oTbody.appendChild( oRow );
	}
	oKanjiTable.appendChild( oTbody );
	with(oKanjiTable){
		id = "oTableC";
		onclick = onclickCell;
		style.fontFamily = "MS ゴシック";
	}
	oTable.appendChild(oKanjiTable);
}
// =================================================================================
function getRandom(maxValue) {
  var now = new Date();
  var num = now.getTime() * now.getSeconds() * Math.random();
  return Math.round(num % maxValue);
}
function setCellAttributes(){
	var oCells = oTableC.cells;
	var iCellLen = oCells.length;
	for (var i=0; i<iCellLen; i++){
		if (oCells(i).innerHTML.indexOf( IMG_TAG ) != -1){
			oCells(i).onclick = fnShowKajiData;
		}
	}
}
function onclickCell(){
  var e, c, oNode;

  e = window.event.srcElement;
  	oNode = e;
	while(oNode.tagName != "TABLE"){
		oNode = oNode.parentElement;
	}
	if (oNode.id == "oTableC" && gbCompleteTableC){
		return;
	} else if (oNode.id == "oTableB" && gbCompleteTableB){
		return;
	}

  if (e.style.backgroundColor == "black"){
  	window.event.cancelBubble = true;
	return;
  }
  c = findCell(e);
  if (c.className == "fixed"){
  	window.event.cancelBubble = true;
  	WinMsg( "The fixed Kanji can not be moved." );
	return;
  }

  if (c != null){
    if (lastSelection == null){
      	selectCell(c);
      	lastSelection = c;
	} else {
  		if (c == lastSelection){
    		deselectCell(lastSelection);
  		} else {
			oNode = c;
			while(oNode.tagName != "TABLE"){
				oNode = oNode.parentElement;
			}
			if (oNode.id == "oTableC" && gbCompleteTableC){
				deselectCell(lastSelection);
				return;
			} else if (oNode.id == "oTableB" && gbCompleteTableB){
				deselectCell(lastSelection);
				return;
			}
	    	c.swapNode(lastSelection);
      		deselectCell(lastSelection);
      		if (oNode.id == "oTableA" || gbCompleteTableC){
				selectCell2(c, "white", "");
			}
	    	nSwaps += 1;
	    	if (nSwaps == 1){
				fnElapsteTimer( true );	// Start Timer
			}
		    numSwaps.innerText = nSwaps;
			if (oNode.id == "oTableC"){
				checkWinner();
			} else {
				checkWinner2();
			}
  		}
  		lastSelection = null;
    }
  }
  window.event.cancelBubble = true;
}
function findCell(e){
  if (e.tagName == "TD"){
    return e;
  } else if (e.tagName == "BODY"){
    return null;
  } else {
    return findCell(e.parentElement);
  }
}

function selectCell(c){
	with(c.runtimeStyle){
	  backgroundColor = "red";
  }
}
function selectCell2(c, sColor, sImg){
	with(c.runtimeStyle){
	  backgroundColor = sColor;
	}
	if (sImg != ""){ c.innerHTML = OPNIMG + DATADIR + sImg + DATAEXT + CLSIMG; }
}

function cancelSelect(){
  if (lastSelection != null){
    deselectCell(lastSelection);
    lastSelection = null;
  }
}

function deselectCell(c){
  with(c.runtimeStyle){
	  backgroundColor = "white";
  }
}
function fnExtractFileNo(sText, w){
	var sp = sText.lastIndexOf( "/" );
	sp = (sp == -1) ? 0 : (sp + 1);
	return(sText.substr(sp, w));
}
function checkWinner(){
  var WrongAns = new Array();
  var bWinner = true;  // Assume we have a winner.
  var sFilename, iRow, iCol, theRow;
  var tempNo, p, q, j, theImgSrc;
  var oCells = oTableC.cells;
  var oCellLen = oCells.length;
  p = 0;
  q = 0;
  j = 0;
  for (p=0; p<oCellLen; p++){
    sFilename = oCells(p).innerHTML;
	if ((KANJI[p].oKanji[1] == CELL_TYPD || KANJI[p].oKanji[1] == CELL_TYPR) && (sFilename.indexOf( IMG_TAG ) != -1)){
		tempNo = fnExtractFileNo(sFilename, NO_WIDTH);
		if (tempNo != KANJI[p].oKanji[0]){
			bWinner = false;
			WrongAns[q] = p;
			q ++;
		}
		j ++;
	} else if (KANJI[p].oKanji[1] != CELL_TYPS){
		bWinner = false;
		WrongAns[q] = p;
		q ++;
	}
  }

  if (bWinner){
	  q = 0;
	  for (p=0; p<oCellLen; p++){
		if ((q < ANS_CELL) && (p == AnsArray[q].No)){
			selectCell2(oCells(p), "SkyBlue", AnsArray[q].Chr);
			q ++;
		} else {
			if (KANJI[p].oKanji[1] != CELL_TYPS) selectCell(oCells(p));
		}
	  }
	  gbCompleteTableC = true;
	  oKanjiAddTable.style.display = "none";
	  oKanjiAnsTable.style.display = "";
  } else if (j == NET_CELL){
	for (var k=0; k<q; k++){
		selectCell2(oCells(WrongAns[k]), "violet", "");
	}
  }
}
function checkWinner2(){
  var sFilename, tempNo, p;
  var oCells = oTableB.cells;
  var oCellLen = oCells.length;

  for (p=0; p<oCellLen; p++){
    sFilename = oCells(p).innerHTML;
    tempNo = fnExtractFileNo(sFilename, NO_WIDTH);
    if (tempNo != ANSCODE[p]) return;
  }
  	fnElapsteTimer( false );	// Timer Stop
	for (p=0; p<oCellLen; p++){
		selectCell2(oCells(p), "gold", ANSCODE[p]+ANSCODE[p]);
	}
	gbCompleteTableB = true;
	fnShowAllAnswers();
	oTopGuide.style.display   = "";
	oLeftGuide.style.display  = "";
	oMeaningBox.style.display = "";
	oReadingBox.style.display = "";
	setCellAttributes();
	fnSetRichMsgBoxCoreData();
	oReadText.value = "";
	oMeanText.value = "";
	WinMsg("Now you may click the Kanji cells to show each Kanji data.");
	oReadText.focus();
}
function fnStripBrackets( aStr ){
    var s = 0;
    var p = aStr.indexOf( "(", s );
    if (p == -1) return aStr;
    var r = aStr.length;
    var q = aStr.indexOf( ")", s );
    var sRet = "";
    do {
        sRet += aStr.substr( s, (p-s) );
        s = q + 1;
        p = aStr.indexOf( "(", s );
        q = aStr.indexOf( ")", s );
    } while( (p != -1) && (q != -1) );
    sRet += aStr.substr( s, (r-s) );
    return sRet;
}
var CUSTOM_TAG = "DEF"; // Defined in <HTML> tag above
function initTitles( sTag, sClass ){
    // arg1: HTML TAG element name (eg."SPAN")
    // arg2: Element Class name (eg. "DEF")
    var oColl = document.body.getElementsByTagName( sTag );
    var iCollLen = oColl.length;
    if (sTag == CUSTOM_TAG){
        for (var i=0; i<iCollLen; i++){
            oColl[i].title = "Click to view extended descripton for " + fnStripBrackets(oColl[i].innerText) + ".";
        }
    } else {
        for (var i=0; i<iCollLen; i++){
            if (oColl[i].className == sClass){
                oColl[i].title = "Click to view extended descripton for " + fnStripBrackets(oColl[i].innerText) + ".";
            }
        }
    }
}
function fnSetReading(){
    // Purpose: provide Hiragana reading for the word
    // This function can be used in the following case only.
    // <Ruby><MY:DEF TipID='M05' onmousedown='fnSetReading();'>****</MY:DEF><RP>...
    var oObj = event.srcElement;
//    alert("oObj.children.length= " + oObj.children.length + " TAG= " + oObj.tagName);
    var oOrg = oObj;
    if (oObj.tagName == "RUBY"){	// Added: 2006/10/16(Mon)-00:20:19 by SKN23
    } else if (oObj.parentElement.tagName == "RUBY"){
        oObj = oObj.parentElement;
    } else if (oObj.children.length > 0 && oObj.children(0).tagName == "RUBY"){
        oObj = oObj.children(0);
    } else if (oObj.children.length == 0){
        oOrg.addMessage = "";
        return;
    } else {
        do {
            oObj = oObj.parentElement;
        } while(oObj.tagName != "RUBY");
    }
    var i = 0;
    while(oObj.children(i).tagName != "RT") i++;
    oOrg.addMessage = oObj.children(i).innerHTML;   // Mod by SKN23 on 2005/01/30(Sun)-22:05:34
}
function fnSetFromNotes(){
    // Purpose: provide Hiragana reading for the word
    // This function can be used in the following case only.
    // <Ruby><MY:DEF TipID='M05' onmousedown='fnSetFromNotes();'>****</MY:DEF><RP>...
    // <span><ruby><rb>腫瘍</rb><rp>(</rp><rt>しゅよう</rt><rp>)</rp></ruby><span id="M01">...</span></span>
    var oObj = event.srcElement;
    var oOrg = oObj;
    var TargetID = F[ oObj.TipID ];
    if (TargetID != null){
        if (TargetID.parentElement.tagName == "SPAN"){
            oObj = TargetID.parentElement;
            var oObjP = oObj;
            var ChildLen = oObjP.children.length;
            var k = 0;
            do {
                oObj = oObjP.children(k);
            }while (++k < ChildLen && oObj.tagName != "RUBY");
            if (oObj.tagName == "RUBY"){
                oObjP = oObj;
                ChildLen = oObjP.children.length;
                k = 0;
                do {
                    oObj = oObjP.children(k);
                }while (++k < ChildLen && oObj.tagName != "RT");
                oOrg.addMessage = (oObj.tagName == "RT") ? oObj.innerHTML : "- Not Defined -<RT>";
            } else {
                oOrg.addMessage = "- Not Defined -<RUBY>";
            }
        } else {
            oOrg.addMessage = "- Not Defined -<SPAN>";
        }
    } else {
        oOrg.addMessage = "- Not Defined -<TipID>";
    }
}
function fnShowTheForm(){
	with(F){
		oReadingResult.value	 = oReadText.value;
		oMeaningResult.value 	 = oMeanText.value;
		oTimeResult.value	 	 = oElpTimer.value;
		oScoreResult.value	 	 = numSwaps.innerText;
		oReadingResult.disabled	 = true;
		oMeaningResult.disabled  = true;
		oTimeResult.disabled	 = true;
		oScoreResult.disabled	 = true;
		fnConstructCountryNameSelect();
		fnConstructFirstLangSelect();
		oHandleName.value = "";
		oMailAddr.value = "(optional)";
		oComment.value  = "(optional,up to 1024 letters)";
		oSubmitForm.style.display = "";
		oHandleName.focus();
	}
}
function fnConstructCountryNameSelect(){
	var	i, j, p, q, theTDZ, oOpt, aCountry, theSelect, theTZD;
	var	tDiff = fnGetTimeZone();
//	tDiff = window.prompt("Enter Test Time Zone");	// for test use only
	tDiff = parseFloat(tDiff);	// for test use only
	var	tZone = new Array(99, 99, 99);
	if (tDiff > 0){
		if (tDiff > DIFF_MAXF){
			p = DIFF_MAXF;
			q = DIFF_MAXF;
		} else {
			p = tDiff;
			q = tDiff - 1;
		}
	} else if (tDiff < 0){
		q = tDiff;
		p = tDiff + 1;
	} else {
		p = tDiff;
		q = tDiff - 1;
	}
	for (i=0, j=0; i<TZD.length; i++){
		if (p >= TZD[i].Diff && TZD[i].Diff >= q){
			tZone[j++] = i;
		}
	}
	theSelect = F.oCountryName;
	if (theSelect.children.length > 0){
		for (i=theSelect.children.length-1; i>=0; i--){
			theSelect.removeChild(theSelect.children[i]);
		}
	}
	oOpt = document.createElement( "OPTION" );
	with(oOpt){
		value	  = "COUNTRY";
		innerText = "Select Country";
	}
	theSelect.appendChild(oOpt);
	theTZD = TZD[tZone[0]];
	for (i=0; i<theTZD.oCells.length; i++){
		aCountry = theTZD.oCells[i];
		oOpt = document.createElement( "OPTION" );
		with(oOpt){
			value	  = aCountry;
			innerText = aCountry;
		}
		theSelect.appendChild(oOpt);
	}
	if (tZone[1] != 99){
		theTZD = TZD[tZone[1]];
		for (i=0; i<theTZD.oCells.length; i++){
			aCountry = theTZD.oCells[i];
			oOpt = document.createElement( "OPTION" );
			with(oOpt){
				value	  = aCountry;
				innerText = aCountry;
			}
			theSelect.appendChild(oOpt);
		}
	}
	if (tZone[2] != 99){
		theTZD = TZD[tZone[2]];
		for (i=0; i<theTZD.oCells.length; i++){
			aCountry = theTZD.oCells[i];
			oOpt = document.createElement( "OPTION" );
			with(oOpt){
				value	  = aCountry;
				innerText = aCountry;
			}
			theSelect.appendChild(oOpt);
		}
	}
	var	oColl = theSelect.children;
	TblQuickSort(oColl, 1, oColl.length);
	fnDelDuplicates(theSelect, 1, oColl.length);
	oOpt = document.createElement( "OPTION" );
	with(oOpt){
		value	  = "Other";
		innerText = "Other";
	}
	theSelect.appendChild(oOpt);
}
function fnConstructFirstLangSelect(){
	var	i, j, oOpt, theSelect;
	var	langArray = new Array(3);
	langArray[0] = window.navigator.browserLanguage;
    with(F.oBody){
        langArray[1] = systemLanguage;
        langArray[2] = userLanguage;
    }

	theSelect = F.oFirstLang;
	if (theSelect.children.length > 0){
		for (i=theSelect.children.length-1; i>=0; i--){
			theSelect.removeChild(theSelect.children[i]);
		}
	}
	oOpt = document.createElement( "OPTION" );
	with(oOpt){
		value	  = "Language";
		innerText = "Select Language";
	}
	theSelect.appendChild(oOpt);

	for (i=0; i<3; i++){
		langArray[i] = fnGetLangNameByCode(langArray[i]);
		oOpt = document.createElement( "OPTION" );
		with(oOpt){
			value = langArray[i];
			innerText = langArray[i];
		}
		theSelect.appendChild(oOpt);
	}

	var	oColl = theSelect.children;
	TblQuickSort(oColl, 1, oColl.length);
	fnDelDuplicates(theSelect, 1, oColl.length);
	oOpt = document.createElement( "OPTION" );
	with(oOpt){
		value	  = "Other";
		innerText = "Other";
	}
	theSelect.appendChild(oOpt);
}
function fnDelDuplicates(oObj, s, e){
	for (var i=e-1; i>=s; i--){
		if (oObj.children[i-1].innerText == oObj.children[i].innerText){
			oObj.removeChild(oObj.children[i]);
		}
	}
}
function setCoreData( oObj ){
	if ((oObj.value == "") && (oSaveCurrentObject != null) && (oSaveCurrentObject.id == "oBtnReset")){
		with(F){
			oReadingResult.value = oReadText.value;
			oMeaningResult.value = oMeanText.value;
			oTimeResult.value	 = oElpTimer.value;
			oScoreResult.value	 = numSwaps.innerText;
			oCountryName2.style.display = "none";
			oFirstLang2.style.display = "none";
			oHandleName.focus();
		}
	}
}
function onChangeContry( oObj ){
	if (oObj.selectedIndex == oObj.options.length-1){
		with(F.oCountryName2){
			style.display = "";
			focus();
		}
	} else {
		with(F.oCountryName2){
			value = "";
			style.display = "none";
		}
	}
}
function onChangeLanguage( oObj ){
	if (oObj.selectedIndex == oObj.options.length-1){
		with(F.oFirstLang2){
			style.display = "";
			focus();
		}
	} else {
		with(F.oFirstLang2){
			value = "";
			style.display = "none";
		}
	}
}
function onChangeReadText( oObj ){
	if (F.oSubmitForm.style.display == ""){
		F.oReadingResult.value = oObj.value;
		if (oSaveCurrentObject != null) oSaveCurrentObject.focus();
	}
}
function onChangeMeanText( oObj ){
	var	oForm = F[ "oAnswerResult" ];	// [Join] button
	if (oForm == null) return;
	if (F.oSubmitForm.style.display == ""){
		F.oMeaningResult.value = oObj.value;
		if (oSaveCurrentObject != null) oSaveCurrentObject.focus();
	} else {
		with(oForm.style){
			position = "absolute";
			top  = oAnswerTableH.offsetTop + oAnswerTableH.offsetHeight + 5;
			left = oAnswerTableH.offsetLeft;
			display = "";
		}
		F.oBtnJoin.focus();
	}
}
// ******************************************************************
// *    Global Variables Definition
// ******************************************************************

var CURRENT_DTIME_PTN = "MM/DD/YYYY hh:mm:ss";
var STANDARD_DATE_ID  = "MDATE";
var ThisVersion       = "3.50"; // 2004/03/11(Thu)-12:00:21
var CPATN   = null; // Current Patern Format String
var NPATN   = null; // New Pattern Format String
var iCurLen = 0;    // Current Pattern Format String Length
var iNewLen = 0;    // New Pattern Format String Length

if (typeof(F) == "undefined"){
    var F = document.all;
}

// ******************************************************************
// *    Data Format Constructor
// ******************************************************************

function fmPack( pos, chr, len ){
    this.Pos    = pos;  // Start Offset: based 0;-1:No data
    this.Chr    = chr;  // Format Qualifier; Default: ""
    this.Len    = len;  // Symbol Length; Default: 0 length
}
function makePatnArray( n ){
    // n: Pattern String Length (max)
    for (var i=0; i<n; i++){
        this[i] = new fmPack( -1, "", 0 );
    }
    this.length = n;
}

function getQualifyLen( cSYM ){
    for (i=0; i<iCurLen; i++){
        if (cSYM == CPATN[i].Chr) return(CPATN[i].Len);
        if (CPATN[i].Chr == "") break;
    }
    return(-1);
}

function getQualifyPos( cSYM ){
    for (i=0; i<iCurLen; i++){
        if (cSYM == CPATN[i].Chr) return(CPATN[i].Pos);
        if (CPATN[i].Chr == "") break;
    }
    return(-1);
}
function getQualifyChr( cSYM ){
    for (i=0; i<iCurLen; i++){
        if (cSYM == CPATN[i].Chr) return(i);
        if (CPATN[i].Chr == "") break;
    }
    return(-1);
}
if (typeof(makeDayOfWeek2) == "undefined"){
    function wdPack2(jday, eday){
        this.Jday = jday;   // JP
        this.Eday = eday;   // EN
    }
    function makeDayOfWeek2(){
        var i = 0;
        this[i++] = new wdPack2( "日", "Sun" ) ; // 0
        this[i++] = new wdPack2( "月", "Mon" ) ; // 1
        this[i++] = new wdPack2( "火", "Tue" ) ; // 2
        this[i++] = new wdPack2( "水", "Wed" ) ; // 3
        this[i++] = new wdPack2( "木", "Thu" ) ; // 4
        this[i++] = new wdPack2( "金", "Fri" ) ; // 5
        this[i++] = new wdPack2( "土", "Sat" ) ; // 6
        this.length = i;
    }
}

function fnUpdateMdate2( sID ){
    var coll = F.tags("SPAN");
    for (var i=0; i<coll.length; i++){
        if (coll[i].className == sID && coll[i].innerText.substr(0,2) == "YY"){  // (oID.innerText.substr(0,2) == "YY") is emergency to avoid twice call
            with(coll[i]){
                style.display = "";
                //                       New Ptn    Current Pattern    Current Data(Date)
                innerText = fnFormatData(innerText, CURRENT_DTIME_PTN, document.lastModified);
            }
        }
    }
}
function fnFormatData( sNewPatn, sCurPatn, sData ){

    // sNewPatn: New output data format (string)    eg. "YYYY/MM/DD(ddd)-hh:mm:ss"
    // sCurPatn: Current input data format (string) eg. "MM/DD/YYYY hh:mm:ss"
    // sDate: Input raw data (string)               eg. 02/26/2003-10:08:30 ---> 2003/02/26(ddd)-10:08:30
    // sDate is expected as single byte data

    /* *---------------------------------------------------------------
    << Pre-Defined Symbols as place holder >>
        Y: Year  Symbol (eg. YYYY stands for 2003, YY is 03)
        M: Month Symbol (eg. MM stands for 10, 02,... so on)
        D: Day   Symbol (eg. DD stands for 06, 28,... so on)
        h: Hour  Symbol (eg. hh stands for 10, 05,... so on)
        m: Min.  Symbol (eg. mm stands for 01, 20,... so on)
        s: Sec.  Symbol (eg. ss stands for 10, 59,... so on)
    ----------------------------------------------------------------* */
    var i, j, k;    // General use purpose
    var aChr;       // Current character
    var pChr;       // Previous character
    var sYEAR;
    var s1 = "";
    var s2 = "";
    var s3 = "";
    var s  = "";

    iNewLen = sNewPatn.length;
    iCurLen = sCurPatn.length;
    CPATN   = new makePatnArray(iCurLen);
    NPATN   = new makePatnArray(iNewLen);

    for (pChr = null, i=0, j=0, k=0; i<iCurLen; i++){
        aChr = sCurPatn.substr(i,1);
        if (aChr == pChr){
            CPATN[k].Len ++;
            continue;
        }
        CPATN[j].Pos = i;
        CPATN[j].Chr = aChr;
        CPATN[j].Len ++;    // 1
        k = j++;
        pChr = aChr;
    }

    for (i=0; i<iCurLen; i++){
        if (CPATN[i].Pos == -1) break;
        s1 += CPATN[i].Chr + " ";
        s2 += CPATN[i].Pos + " ";
        s3 += CPATN[i].Len + " ";
    }

    for (pChr = null, i=0, j=0, k=0; i<iNewLen; i++){
        aChr = sNewPatn.substr(i,1);
        if (aChr == pChr){
            NPATN[k].Len ++;
            continue;
        }
        NPATN[j].Pos = i;
        NPATN[j].Chr = aChr;
        NPATN[j].Len ++;    // 1
        k = j++;
        pChr = aChr;
    }

    s1 = "";
    s2 = "";
    s3 = "";
    for (i=0; i<iNewLen; i++){
        if (NPATN[i].Pos == -1) break;
        s1 += NPATN[i].Chr + " ";
        s2 += NPATN[i].Pos + " ";
        s3 += NPATN[i].Len + " ";
    }

    for (i=0; i<iNewLen; i++){
        if ((nc = NPATN[i].Chr) == "") break;
        cp = getQualifyChr(nc);
        if ((cp != -1) && (CPATN[cp].Len == NPATN[i].Len)){ // nc is found in sData
            s += sData.substr(CPATN[cp].Pos, CPATN[cp].Len);
        } else if ((cp != -1) && ((CPATN[cp].Chr == 'Y') && (CPATN[cp].Len != NPATN[i].Len))){
            if (NPATN[i].Len == 4){
                sYEAR = sData.substr(CPATN[cp].Pos, CPATN[cp].Len);
                if (sYEAR > "50"){
                    sYEAR = "19" + sYEAR;   // 19XX
                } else {
                    sYEAR = "20" + sYEAR;   // 20XX
                }
            } else {
                sYEAR = sData.substr(CPATN[cp].Pos+(CPATN[cp].Len-NPATN[i].Len), NPATN[i].Len);
            }
            s += sYEAR;
        } else if (cp == -1){
            if (NPATN[i].Len == 1){ // should be a delimiter such as "/"
                s += ((nc == 'S') ? ' ' : nc);
            } else if ((nc == "d") && (NPATN[i].Len >= 3)){ // ddd ===> day of week
                var d = new Date();
                pY = getQualifyPos('Y'); lY = getQualifyLen('Y');
                pM = getQualifyPos('M'); lM = getQualifyLen('M');
                pD = getQualifyPos('D'); lD = getQualifyLen('D');
                sYEAR = (pY >= 0) ? sData.substr(pY, lY) : d.getFullYear();
                if (sYEAR.length == 2){
                    if (sYEAR > 50){
                        sYEAR = "19" + sYEAR;   // 19XX
                    } else {
                        sYEAR = "20" + sYEAR;   // 20XX
                    }
                }
                var iYEAR  = eval(sYEAR);
                var iMONTH = eval(sData.substr(pM, lM));
                var iDAY   = eval(sData.substr(pD, lD));
                d = new Date(iYEAR, iMONTH-1, iDAY);
                day = d.getDay();
                var DaysOfWeek = new makeDayOfWeek2();
                s += DaysOfWeek[day].Eday;
                DaysOfWeek = null;
            } else {
                s += sNewPatn.substr(NPATN[i].Pos, NPATN[i].Pos);   // copy from NewPatn
            }
        }
    }
    return s;
}

// =================================================================================
function fnInitProc(){
	fnCreateCrossTable(sKCROSSWORD_TABLE, MAX_ROWS, MAX_COLS);
	fnCreateAddTable(sADDLIST_TABLE, MAX_ROWS, MAX_LIST);
	fnCreateAnsTable(sANSLIST_TABLE, MIN_ROWS, ANS_CELL);
	fnCreateGuideTables();
//	object.setExpression(sPropertyName, sExpression [, sLanguage]);
	oElpTimer.value = INIT_TIMES;
	fnUpdateMdate2( sDATE_CLASS_ID );
}
// #################################################################################
// #	<< End of KanjiCross.js >> (C) 2007 Southern Cross Virtual Co., Ltd. (v1.3)
// #################################################################################
