var TypingPractice = {

	create: function() {
		this.dbConnectManager = new DBConnectManager();
		sessionStorageManager.setRecord(0);

		var self = this;

		this.isOnStage = false;

		this.initTypingData();
		sessionStorageManager.setIsNewAppHighestRecord(false);

		var experienceAppTimer = new ExperienceAppTimer();
		experienceAppTimer.setTimeOverListener(
			(function() { this.timeOver(); }).bind(this)
		);

		game.stage.backgroundColor = '#4d4d4d';

		// top ui
		var screenTopUI = new ScreenTopUI();
		screenTopUI.makeBackButton( (function() { this.back(); }).bind(this) );
		screenTopUI.makeFullScreenButton();


		this.typingScore = new TypingScore();
		this.stageTimer = new StageTimer( TypingPractice.STAGE_TIMER_SEC, (function() {
			self.isOnStage = false;

			// self.goResult();
			self.timeOver();
		}));


		// typing content
		var typingContentBG = new TypingContentBG();
		typingContentBG.makePracticeContentBG();

		this.animalList = new AnimalList(90);


		var TYPING_CONTENT_Y = 200;

		textStyleBasic.font = "bold 84px Times New Roman";
		this.textTypingContent = game.add.text(game.world.centerX, TYPING_CONTENT_Y, "", textStyleBasic)
		.setShadow(3, 3, 'rgba(0, 0, 0, 1)', 2)
		.addColor(TypingPractice.COLOR_CONTENT_INPUT, 0);
		this.textTypingContent.anchor.set(0.5);

		this.pronounceText = this.makeDefaultText(game.world.centerX, TYPING_CONTENT_Y + 80);
		this.pronounceText.style.fill = MainColor.LIGHT_CHOCO_STRING;
		this.pronounceText.addColor(MainColor.CHOCO_STRING, 2);
		this.pronounceText.setShadow(1, 1, 'rgba(0, 0, 0, 1)', 1);
		// this.pronounceText.stroke = MainColor.BLACK_STRING;
		// this.pronounceText.strokeThickness = 1;


		this.textTypingBracket = game.add.text(game.world.centerX, TYPING_CONTENT_Y, "[      ]", textStyleBasic)
		.setShadow(3, 3, 'rgba(0, 0, 0, 0.5)', 2)
		.addColor(TypingPractice.COLOR_BRACKET, 0);
		this.textTypingBracket.anchor.set(0.5);


		// textStyleBasic.font = "32px Arial";
		var OFFSET_WORD_X = 70;

		var textDoneColor = [ '#99994d', '#77774d', '#66664d' ];
		this.textTypingContentsDone = [];
		for(var i = 0; i < TypingPractice.TYPING_CONTENT_DONE_COUNT; i++) {
			this.textTypingContentsDone[i] = game.add.text(
				game.world.centerX - 200 - i * OFFSET_WORD_X, TYPING_CONTENT_Y,
				"", textStyleBasic
			);
			this.textTypingContentsDone[i].addColor(textDoneColor[0], 0);
			this.textTypingContentsDone[i].anchor.set(0.5);
		}

		var textPreviewColor = [ '#666666', '#888888', '#777777' ];
		this.textTypingContentPreview = [];
		for(var i = 0; i < TypingPractice.TYPING_CONTENT_PREVIEW_COUNT; i++) {
			this.textTypingContentPreview[i] = game.add.text(
				game.world.centerX + 200 + i * OFFSET_WORD_X,
				TYPING_CONTENT_Y, "", textStyleBasic
			);
			this.textTypingContentPreview[i].addColor(textPreviewColor[0], 0);
			this.textTypingContentPreview[i].anchor.set(0.5);
		}

		// keyboard
		this.keyMapper = new KeyMapper();
		this.keyboard = null;
		if(sessionStorageManager.getPlayingAppName().indexOf("korean") > 0)
			this.keyboard = new Keyboard(this.keyMapper, Keyboard.KOREAN, Keyboard.NO_OFFSET_POS_Y);
		else
			this.keyboard = new Keyboard(this.keyMapper, Keyboard.ENGLISH, Keyboard.NO_OFFSET_POS_Y);
		this.keyboard.addCallback(
			Phaser.KeyCode.ESC,	// keyCode
			null,	// keyDownHandler
			(function() { this.back(); }).bind(this),	// keyUpHandler
			"typing_practice"	// callerClassName
		);

		game.input.keyboard.processKeyPress = (function(event) {
			if(self.isOnStage === false)
				return;

			self.checkTypingContents(event);
		});
		this.shiftKey = game.input.keyboard.addKey(Phaser.Keyboard.SHIFT);

		// hands
		this.leftHand = new LeftHand(this.keyMapper);
		this.rightHand = new RightHand(this.keyMapper);



		// bottom ui
		var screenBottomUI = new ScreenBottomUI();
		// screenBottomUI.printBottomUILeftText("");
		screenBottomUI.printCenterText(sessionStorageManager.getPlayingAppKoreanName());
		screenBottomUI.printRightText(sessionStorageManager.getPlayerName());


		this.startGame();
		// this.countDown();
	},


	back: function() {
		sessionStorageManager.resetPlayingAppData();
		location.href = '../../web/client/main_menu.html';
	},

	startGame: function() {
		this.isOnStage = true;
		this.stageTimer.start();

		this.showTypingPracticeContents();
		this.showHighlightKey();
		this.moveHands();
	},

	timeOver: function() {
		this.isOnStage = false;

		for(var i = 0; i < TypingPractice.TYPING_CONTENT_DONE_COUNT; i++) {
			this.textTypingContentsDone[i].text = "";
		}

		this.textTypingBracket.text = "";

		this.textTypingContent.clearColors();
		this.textTypingContent.addColor(TypingPractice.COLOR_CONTENT_RIGHT, 0);
		this.textTypingContent.text = "= 연습 끝 =";

		for(var i = 0; i < TypingPractice.TYPING_CONTENT_PREVIEW_COUNT; i++) {
			this.textTypingContentPreview[i].text = "";
		}

		this.leftHand.moveToDefaultPosition();
		this.rightHand.moveToDefaultPosition();

		this.animalList.stopAnimation();
		var timeOverText = new TimeOverText();

		sessionStorageManager.setRecord(this.typingScore.getScore());
		this.updateResultRecord();

		game.time.events.add(Phaser.Timer.SECOND * 2, this.goResult, this);
	},

	updateResultRecord: function() {
		if(sessionStorageManager.getMaestroAccountType() < 100) {	// experience account
			this.dbConnectManager.updateResultRecord(
				sessionStorageManager.getMaestroID(),
				sessionStorageManager.getPlayerID(),
				sessionStorageManager.getPlayingAppID(),
				sessionStorageManager.getRecord()
			);
		}
	},

	goResult: function() {
		location.href = '../../web/client/result.html';
	},

	initTypingData: function() {
		var typingTextMan = new TypingTextManager();

		var typingPracticeContents = this.loadPracticeContent();
		// console.log(typingPracticeContents);
		typingTextMan.makePracticeContents(typingPracticeContents, 30);
		this.typingRandomContents = typingTextMan.getContents();
		// console.log(this.typingRandomContents);
		this.typingContentLength = this.typingRandomContents.length;
		this.typingIndex = 0;

		this.playingAnimalIndex = 0;
	},


	makeDefaultText: function(x, y) {
		var defaultText = game.add.text(x, y, "");
		defaultText.anchor.set(0.5, 0.5);
		// defaultText.font = "Nanum Gothic Coding";
		defaultText.font = "Times New Roman";
		defaultText.fontSize = 26;
		defaultText.fontWeight = "normal";
		defaultText.style.fill = "white";

		return defaultText;
	},

	loadPracticeContent: function() {
		var appName = "";
		if(isTypingTestApp())
			appName = sessionStorageManager.getPlayingAppName().substring(5);
		else if(isTypingPracticeApp())
			appName = sessionStorageManager.getPlayingAppName().substring(9);

		var testContent = [];

		switch(appName) {
			case "korean_basic":
			testContent = koreanBasicWordList;
			break;
			case "korean_left_upper":
			testContent = koreanLeftUpperWordList;
			break;
			case "korean_second_finger":
			testContent = koreanSecondFingerWordList;
			break;
			case "korean_right_upper":
			testContent = koreanRightUpperWordList;
			break;
			case "korean_left_lower":
			testContent = koreanLeftLowerWordList;
			break;
			case "korean_right_lower":
			testContent = koreanRightLowerWordList;
			break;
			case "korean_left_upper_double":
			testContent = koreanLeftUpperDoubleWordList;
			break;
			case "korean_right_upper_double":
			testContent = koreanRightUpperDoubleWordList;
			break;
			case "korean_word":
			testContent = koreanWordList;
			break;
			case "korean_sentence":
			testContent = koreanSentenceList;
			break;

			case "english_basic":
			testContent = englishBasicWordList;
			/*
			testContent = [
				"a",
				"C",
				"n",
				"J",
				"t",
				"e",
				"s",
				"X",
				"v",
				"b",
				"D",
				"i",
				"k",
				"N",
			];
			*/
			break;
			case "english_left_upper":
			testContent = englishLeftUpperWordList;
			break;
			case "english_second_finger":
			testContent = englishSecondFingerWordList;
			break;
			case "english_right_upper":
			testContent = englishRightUpperWordList;
			break;
			case "english_left_lower":
			testContent = englishLeftLowerWordList;
			break;
			case "english_right_lower":
			testContent = englishRightLowerWordList;
			break;
			case "english_upper_lower":
			testContent = englishUpperLowerWordList;
			break;
			case "english_word":
			testContent = englishWordList;
			break;
			case "english_sentence":
			testContent = englishSentenceList;
			break;
		}

		return testContent;
	},

	isEnglishAlphabet: function(letter) {
		var patternEnglishAlphabet = /[a-zA-Z]/;
		if(patternEnglishAlphabet.test(letter))
			return true;
		else
			return false;
	},

	getPronounce: function(letter) {
		var pronounceArray = [
			"에이", "비", "씨", "디", "이", "에프", "지", "에이치", "아이",
			"제이", "케이", "엘", "엠", "엔", "오", "피", "큐", "알",
			"에스", "티", "유", "브이", "더블유", "엑스", "와이", "지(제트)"
		];

		var lowercaseLetter = letter.toLowerCase();
		var letterIndex = lowercaseLetter.charCodeAt(0) - "a".charCodeAt(0);
		return pronounceArray[letterIndex];
	},

	showPronounceText: function(letter) {
		if(!this.isEnglishAlphabet(letter)) {
			this.pronounceText.text = "";
			return;
		}

		this.pronounceText.text = letter.toUpperCase() + " " + this.getPronounce(letter);
	},

	showTypingPracticeContents: function() {
		for(var i = 0; i < TypingPractice.TYPING_CONTENT_DONE_COUNT; i++) {
			var doneIndex = this.typingIndex - i - 1;
			if(doneIndex < 0) {
				this.textTypingContentsDone[i].text = "";
			} else {
				this.textTypingContentsDone[i].text = this.typingRandomContents[doneIndex];
			}
		}

		if(this.typingIndex == this.typingContentLength) {
			this.textTypingContent.text = "";
			return;
		}

		this.textTypingContent.text = this.typingRandomContents[this.typingIndex];
		this.showPronounceText(this.textTypingContent.text);

		for(var i = 0; i < TypingPractice.TYPING_CONTENT_PREVIEW_COUNT; i++) {
			var previewIndex = this.typingIndex + i + 1;
			if(previewIndex < this.typingRandomContents.length)
				this.textTypingContentPreview[i].text = this.typingRandomContents[previewIndex];
			else
				this.textTypingContentPreview[i].text = "";
		}
	},

	hideHighlightKey: function() {
		var prevText = this.typingRandomContents[this.typingIndex];
		if(prevText === undefined)
			return;

		this.keyboard.hideHighlight(prevText);
	},

	showHighlightKey: function() {
		var typingText = this.typingRandomContents[this.typingIndex];
		if(typingText === undefined)
			return;

		this.keyboard.showHighlight(typingText, this.leftHand, this.rightHand);
	},

	moveHands: function() {
		var typingText = this.typingRandomContents[this.typingIndex];
		if(typingText === undefined)
			return;

		var key = this.keyboard.getKeyOfText(typingText);
		var handSide = key.handSide;
		if(handSide === KeyButton.LEFT_HAND) {
			this.leftHand.moveTo(key);

			if(this.keyMapper.isShiftText(typingText)) {
				var shiftRightKey = this.keyboard.getKey("ShiftRight");
				shiftRightKey.showHighlight();
				this.rightHand.moveTo(shiftRightKey);
			} else {
				this.rightHand.moveToDefaultPosition();
			}
		} else {
			this.rightHand.moveTo(key);

			if(this.keyMapper.isShiftText(typingText)) {
				var shiftLeftKey = this.keyboard.getKey("ShiftLeft");
				shiftLeftKey.showHighlight();
				this.leftHand.moveTo(shiftLeftKey);
			} else {
				this.leftHand.moveToDefaultPosition();
			}
		}
	},

	getKeyCode: function(text) {
		return this.keyMapper.getKeyIDOfText(text);
	},

	isKeyPressed: function(inputContent, typingContent) {
		var inputContentKeyCode = this.getKeyCode(inputContent);
		var typingContentKeyCode = this.getKeyCode(typingContent);

		if(inputContentKeyCode !== typingContentKeyCode)
			return false;

		var isShiftInputContent = this.shiftKey.isDown;
		var isShiftTypingContent = this.keyMapper.isShiftText(typingContent);

		if(isShiftInputContent !== isShiftTypingContent)
			return false;

		return true;
	},

	checkTypingContents: function(event) {
		var inputContent = event.key;
		if(inputContent == undefined)
			inputContent = String.fromCharCode(event.charCode);
		var typingContent = this.typingRandomContents[this.typingIndex];

		if(this.isKeyPressed(inputContent, typingContent)) {
			var plusScore = 1;
			this.typingScore.add(plusScore);
			var scoreText = new ScoreText(
				game.world.centerX,
				TypingContentBG.POS_Y_CONTENT_BOX_TYPING_PRACTICE,
				plusScore
			);

			var animalLevelID = Animal.animalLevelIDByRecord(this.typingScore.getScore(), Animal.TYPE_PRACTICE);
				// console.log(animalLevelID);
				// console.log(this.playingAnimalIndex);
			if(animalLevelID > this.playingAnimalIndex) {
				this.playingAnimalIndex = animalLevelID;
				this.animalList.activate(this.playingAnimalIndex);
				this.animalList.tweenAnimation(Animal.ANIMATION_TYPE_CHANGE);
			}
			this.playNextContent();

			if(this.typingIndex === this.typingContentLength) {
				// this.goResult();
			}
		} else {
			if(this.playingAnimalIndex > 0)
				this.playingAnimalIndex--;
			var prevScore = this.typingScore.getScore();
			this.typingScore.set(Animal.getAnimalPracticeTypingCount(this.playingAnimalIndex));
			var presentScore = this.typingScore.getScore();

			if(presentScore - prevScore < 0) {
				var scoreText = new ScoreText(
					game.world.centerX,
					TypingContentBG.POS_Y_CONTENT_BOX_TYPING_PRACTICE,
					presentScore - prevScore
				);
				scoreText.setScale(1.5);
			}

			this.animalList.activate(this.playingAnimalIndex);
			this.animalList.tweenAnimation(Animal.ANIMATION_TYPE_DAMAGE);
		}
	},

	playNextContent: function() {
		this.hideHighlightKey();

		this.typingIndex++;
		this.showTypingPracticeContents();
		this.showHighlightKey();
		this.moveHands();
	}
}


TypingPractice.TYPING_CONTENT_PREVIEW_COUNT	= 3;
TypingPractice.TYPING_CONTENT_DONE_COUNT	= 3;
TypingPractice.TYPING_COUNT_PLUS_ENTER		= 1;

TypingPractice.OFFSET_RIGHT_ALIGN			= 10;

TypingPractice.STAGE_TIMER_SEC				= 30;

TypingPractice.COLOR_CONTENT_INPUT			= "#dddddd";
TypingPractice.COLOR_BRACKET				= "#dddd70";
TypingPractice.COLOR_CONTENT_RIGHT			= "#ffff4d";