/**
 * Player.js
 */

var vocabularies = new Array();
var sound_url_cache = new Array();
var image_url_cache = new Array();
var Player = Class.create({
	initialize: function(user, permission, shortcut) {
		this.index = null;
		this.card_index = null;
		this.voca_index = null;
		
		this.position = 0;
		this.sound_auto_play = true;
		
		this.user = user;
		this.font_size = 1;
		
		this.image_visible = true;
		this.name_visible = true;
		this.mean_visible = true;
		this.example_visible = true;
		
		this.hideTimerCtrl();
		$('view').update('');
		this.current_div = new Element('div').addClassName('notice').update('데이터를 불러오는 중');
		$('view').appendChild(this.current_div);
		this.resize();
		
		this.delay_time = 3;
		
		this.quiz = new Quiz(this);
		
		this.mode = 'player';
		this.updateControls();
		this.mini_mode = false;
		
		this.is_data_loaded = false;
		
		this.sound_plugin = null;
		this.image_plugin = null;
		this.style_plugin = null;
		
		this.background = null;
		this.name_style = {'background': null, 'font': null, 'color': 'black', 'size': 14, 'bold': false, 'italic': false};
		this.mean_style = {'background': null, 'font': null, 'color': 'black', 'size': 10, 'bold': false, 'italic': false};
		this.example_style = {'background': null, 'font': null, 'color': 'black', 'size': 9, 'bold': false, 'italic': false};
		
		this.demo_mode = false;
		this.updateButtonPosition();
		
		this.learning_log = {'date': null, 'log': []};
		this.permission = permission;
		
		this.shortcut = shortcut;
	},
	
	load: function(request)	{
		try
		{
			var data = request.responseText.evalJSON();
			
			this.learning_log.date = data.date;
			
			this.book = data.book;
			
			this._setSoundPlugin(data.sound_plugin);
			this._setImagePlugin(data.image_plugin);
			this._setStylePlugin(data.style_plugin);
			
			vocabularies = data.vocabularies;
			vocabularies.pop();
			
			this.initTimer();
			this.initShortcut();
			
			this.is_data_loaded = true;
			
			if (vocabularies.length > 0)
			{
				this.index = this.card_index = $A($R(0, vocabularies.length - 1));
				
				this.position = 1;
				this.update(1);
				this.sound();
				
				if (this.user)
					this.initLearningLogTimer();
				
				return true;
			}
			else
			{
				this.current_div.remove();
				this.current_div = new Element('div').addClassName('notice').update('암기할 단어가 존재하지 않습니다.');
				$('view').appendChild(this.current_div);

				return false;
			}
		}
		catch (e)
		{
			this.onDataLoadFailed();
			this.is_data_loaded = false;
			return false;
		}
	},
	
	onDataLoadFailed: function() {
		this.current_div.remove();
		this.current_div = new Element('div').addClassName('notice').update('데이터 불러오기에 실패하였습니다.<br /><a href="javascript:;" id="retry_button" onclick="location.reload(); return false;" title="재시도" class="button"><span>재시도</span></a>');
		$('view').appendChild(this.current_div);
	},

	initLearningLog: function(date) {
		if (this.learning_log.date != date)
		{
			this.learning_log.log.clear();
			this.learning_log.date = date;
		}
	},
	
	initLearningLogTimer: function()
	{
		this.learning_timer = new PeriodicalExecuter(function() {
			player.updateLearningLog(true);
		}, 30);
	},

	startDemoMode: function() {
		this.demo_mode = true;
		this._setSoundPlugin(true);
		this.setSoundAutoPlay(true);
	},
	
	_setSoundPlugin: function(plugin_data) {
		if (plugin_data)
		{
			this.sound_plugin = plugin_data;
			this.updateButtonPosition();
			this.updateControls();
		}
	},
	
	_setImagePlugin: function(plugin_data) {
		if (plugin_data)
			this.image_plugin = plugin_data;
		
	},
	
	_setStylePlugin: function(plugin_data) {
		if (plugin_data)
		{
			this.style_plugin = plugin_data;
			this.loadStyle();
		}
	},
	
	updateButtonPosition: function() {
		var top = 30;
		if (this.mode == 'player')
		{
			$('mini_button').style.top = top + 'px';
			if (this.sound_plugin != null)
			{
				top += 20;
				$('sound_button').style.top = top + 'px';
			}
			top += 20;
		}
		$('font_big_button').style.top = top + 'px';
		top += 15;
		$('font_small_button').style.top = top + 'px';
	},
	
	setSoundAutoPlay: function(enable) {
		this.sound_auto_play = enable;
	},
	
	initVocaIndex: function() {
		this.voca_index = this.card_index.reject(function(idx) {
			return vocabularies[idx][4];
		});
		
		this.voca_index = this.voca_index.sort(function(a, b) {
			var vocabulary1 = vocabularies[a][0]; // name
			var vocabulary2 = vocabularies[b][0]; // name
								
			if (vocabulary1 > vocabulary2)
				return 1;
			else if (vocabulary1 < vocabulary2)
				return -1;
			else
				return 0;
		});
		
		return this.voca_index;
	},
	
	getVocaIndex: function() {
		return this.voca_index ? this.voca_index : this.initVocaIndex();
	},

	order: function(type) {
		if (!this.voca_index && type > 0)
			this.initVocaIndex();
		
		switch (type)
		{
			default:
				this.index = this.card_index;
				$('order_type0').addClassName('selected');
				$('order_type1').removeClassName('selected');
				$('order_type2').removeClassName('selected');
				break;

			case 1:
				this.index = this.voca_index;
				$('order_type0').removeClassName('selected');
				$('order_type1').addClassName('selected');
				$('order_type2').removeClassName('selected');
				break;
				
			case 2:
				this.index = this.voca_index.sort(function(a, b){
					return Math.floor(Math.random() * 3) - 1;
				});
				$('order_type0').removeClassName('selected');
				$('order_type1').removeClassName('selected');
				$('order_type2').addClassName('selected');
				break;
		}
		
		this.update(1);
		this.sound();
	},
	
	previous: function()	{
		if (this.is_playing)
		{
			this.stop();
			this.play();
		}

		if (this.position > 1)
			this.update(this.position - 1);
		else
			this.update(this.index.length);
		this.sound();
	},
	
	next: function() {
		if (this.is_playing)
		{
			this.stop();
			this.play();
		}
		
		if (this.position < this.index.length)
			this.update(this.position + 1);
		else
			this.update(1);
		this.sound();
	},
	
	createVocabularyDiv: function(index) {
		var vocabulary = vocabularies[index];
		
		var vocabulary_div = new Element('div').addClassName('vocabulary');
		
		if (this.image_plugin && this.image_visible) // image
		{
			var image_element = new Element('div').addClassName('image').update('<img src="/img/icon/image_loading.gif" alt="이미지 로딩중..."/>');
			this.loadImage(index, image_element);
			vocabulary_div.appendChild(image_element);
			this.loadImage((index + 1) % this.index.length, null);
		}
		
		if (vocabulary[0].length > 0) // name
		{
			var name_element = new Element('div').addClassName('name').update(vocabulary[0]); // name
			//updateFontSize(name_element, this.font_size * 1.4, this.font_size * 2.3);
			updateStyle(name_element, this.name_style, this.font_size);
			if (this.name_visible == false)
				name_element.hide();
			vocabulary_div.appendChild(name_element);
		}
		
		if (vocabulary[1].length > 0) // mean
		{
			var mean_element = new Element('div').addClassName('mean').update(vocabulary[1]); // mean
			//updateFontSize(mean_element, this.font_size * 1.1, this.font_size * 1.9);
			updateStyle(mean_element, this.mean_style, this.font_size);
			if (this.mean_visible == false)
				mean_element.hide();
			vocabulary_div.appendChild(mean_element);
		}
		
		if (vocabulary[2].length > 0) // example
		{
			var example_element = new Element('div').addClassName('example').update(vocabulary[2]); // example
			//updateFontSize(example_element, this.font_size, this.font_size * 1.5);
			updateStyle(example_element, this.example_style, this.font_size);
			if (this.example_visible == false)
				example_element.hide();
			vocabulary_div.appendChild(example_element);
		}

		return vocabulary_div;
	},
	
	update: function(new_position) {
		if (new_position != undefined)
		{
			this.current_div.remove();

			if (this.index.length > 0)
			{
				if (new_position > this.index.length)
					new_position = this.index.length;
				
				var index = this.index[new_position - 1];
				
				if (this.user && !this.learning_log.log.include(vocabularies[index][3])) // viid
					this.learning_log.log.push(vocabularies[index][3]); // viid
					
				if (vocabularies[index][4])
					$('break_button').addClassName('disable');
				else
					$('break_button').removeClassName('disable');
	
				this.current_div = this.createVocabularyDiv(index);
				$('view').appendChild(this.current_div);
			
				this.position = new_position;
			}
			else
			{
				this.stop();
				this.current_div = new Element('div').addClassName('notice').update('암기할 단어가 존재하지 않습니다.');
				$('view').appendChild(this.current_div);
				$('break_button').addClassName('disable');
				this.position = 0;
			}
		}
		
		this.updatePositionCtrl();
		this.updateView();
	},
	
	_makePluginUrl: function(type, url, index, callback)
	{
		url = url.gsub(/%id%/, index + 1);
		url = url.gsub(/%name%/, encodeURIComponent(vocabularies[index][0].strip())); // name
		url = url.gsub(/%name_l%/, encodeURIComponent(vocabularies[index][0].toLowerCase().strip())); // name_l
		url = url.gsub(/%mean%/, encodeURIComponent(vocabularies[index][1].strip())); // mean
		url = url.gsub(/%example%/, encodeURIComponent(vocabularies[index][2].strip())); // example
	
		if (type == 'url')
		{
			new Ajax.Request(
				'/player/read_url',
				{
					parameters: {
						url: url
					},
					onSuccess: function(request)
					{
						callback(request.responseText);
					}
				}
			);
		}
		else
		{
			callback(url);
		}
	},
	
	sound: function(play)
	{
		if (play == undefined && this.sound_auto_play != true || this.sound_plugin == null)
			return;
		
		var index = this.index[this.position - 1];
		
		if (sound_url_cache[index] != undefined)
		{
			playSound(sound_url_cache[index][1], sound_url_cache[index][0]);
			return;
		}
		
		if (this.demo_mode)
		{
			playSound('mp3', '/mp3/' + (index + 1) + '.mp3');
			return;
		}
		
		var data = this.sound_plugin;
		
		this._makePluginUrl(data.type, data.url, index, function(url) {
			sound_url_cache[index] = [url, data.file_type];
			playSound(data.file_type, url);
		});
	},
	
	loadImage: function(index, image_element) {
		if (this.image_plugin == null)
			return;
		
		if (image_url_cache[index] != undefined)
		{
			if (image_element)
			{
				if (!image_url_cache[index].blank())
				{
					image_element.update('<img src="' + image_url_cache[index] + '" onload="player.resizeImage(this);" />');
				}
				else
				{
					image_element.update('');
					this.updateView();
				}
			}
			return;
		}
		
		var data = this.image_plugin;
		
		this._makePluginUrl(data.type, data.url, index, function(url) {
			image_url_cache[index] = url;
			if (image_element)
			{
				if (!url.blank())
				{
					image_element.update('<img src="' + url + '" onload="player.resizeImage(this);" />');
				}
				else
				{
					image_element.update('');
					player.updateView();
				}
			}
			else if (url != '')
			{
				$('PreloadImageDiv').update('<img src="' + url + '" style="height: 0px; width: 0px;" />');
			}
		});
	},
	
	resizeImage: function(image) {
		var width = document.viewport.getWidth() * 0.7;
		if (image.width > width)
			image.width = width;
		this.updateView();
	},
	
	loadStyle: function() {
		if (this.style_plugin == null)
			return;
		
		var data = this.style_plugin;
		
		this.background = data.background;
		document.body.style.background = data.background;
		this.name_style = setStyleArray(this.name_style, data.name_bg, data.name_font, data.name_color, data.name_size, data.name_ext);
		this.mean_style = setStyleArray(this.mean_style, data.mean_bg, data.mean_font, data.mean_color, data.mean_size, data.mean_ext);
		this.example_style = setStyleArray(this.example_style, data.example_bg, data.example_font, data.example_color, data.example_size, data.example_ext);
	},
	
	toggleName: function(visible) {
		if (visible != undefined && visible == this.name_visible)
			return;
		this.name_visible = !this.name_visible;

		setCookie('name_visible', this.name_visible ? '1' : '0', null);
		
		$('view').select('div.name').each(function(obj) {
			obj.toggle();
		});
		this.update();
		$('show_name').toggleClassName('selected');
		
		return this.name_visible;
	},
	
	toggleMean: function(visible) {
		if (visible != undefined && visible == this.mean_visible)
			return;
		this.mean_visible = !this.mean_visible;
		
		setCookie('mean_visible', this.mean_visible ? '1' : '0', null);
		
		$('view').select('div.mean').each(function(obj) {
			obj.toggle();
		});
		this.update();
		$('show_mean').toggleClassName('selected');
		
		return this.mean_visible;
	},
	
	toggleExample: function(visible) {
		if (visible != undefined && visible == this.example_visible)
			return;
		this.example_visible = !this.example_visible;
		
		setCookie('example_visible', this.example_visible ? '1' : '0', null);
		
		$('view').select('div.example').each(function(obj) {
			obj.toggle();
		});
		this.update();
		$('show_example').toggleClassName('selected');
		
		return this.example_visible;
	},
	
	countdown: function() {
		if (this.time <= 0)
		{
			this.hideTimerCtrl();
			this.next();
			this.time = this.delay_time;
		}
		
		if (this.time < 4)
		{
			this.showTimerCtrl();
			$('timer').update(this.time);
		}
		--this.time;
	},
	
	showTimerCtrl: function() {
		$('timer_ctrl').setStyle({ position: '', top: '' });
	},
	
	hideTimerCtrl: function() {
		$('timer_ctrl').setStyle({ position: 'absolute', top: '-50px' });
	}, 
	
	initTimer: function() {
		this.time = this.delay_time;
	},
	
	play: function() {
		if (!this.is_playing && this.index.length > 0)
		{
			$('play_pause_button').addClassName('pause');
			this.is_playing = true;
			this.initTimer();
	
			this.countdown();
			this.timer = new PeriodicalExecuter(function() {
				if (player)
					player.countdown();
			}, 1);
		}
	},
	
	stop: function() {
		if (this.is_playing)
		{
			$('play_pause_button').removeClassName('pause');
			this.timer.stop();
			this.hideTimerCtrl();
			this.is_playing = false;
		}
	},
	
	doPlayPause: function() {
		if (this.is_playing)
		{
			this.stop();
		}
		else
		{
			this.play();
			this.sound();
		}
	},
	
	updateView: function() {
		var header_height = 0;
		var toolbar_height = 0;
		if (!this.mini_mode)
		{
			header_height = $('header').getHeight();
			toolbar_height = header_height + $('footer').getHeight();
		}
		
		var content_height = document.viewport.getHeight() - toolbar_height;
		if (content_height > 0)
		{
			var view_element = null;
			switch (this.mode)
			{
			case 'player':
				view_element = $('view');
				break;
			case 'quiz':
				view_element = $('quiz');
				break;
			default:
				view_element = $('settings');
				break;
			}
			
			view_element.style.height = '';
			var margin = content_height - view_element.getHeight();
			
			if (margin >= 0)
			{
				$('content').style.top = header_height + (margin / 2) + 'px';
				$('mini_button').style.right = '5px';
				$('sound_button').style.right = '3px';
				$('font_small_button').style.right = '5px';
				$('font_big_button').style.right = '5px';
			}
			else
			{
				$('content').style.top = header_height + 'px';
				view_element.style.height = content_height + 'px';
				$('mini_button').style.right = '20px';
				$('sound_button').style.right = '18px';
				$('font_small_button').style.right = '20px';
				$('font_big_button').style.right = '20px';
			}
		}
	},
	
	updatePositionCtrl: function() {
		$('position').update(this.position + ' / ' + this.index.length);
	},
	
	complete: function() {
		if (this.user)
		{
			var current_position = this.position;
			var index = this.index[current_position - 1];
			if (vocabularies[index][4])
				return;
			
			if (this.permission)
			{
				var viid = this.deleteVocabulary();
				new Ajax.Request('/player/complete/' + viid + '/book_id:' + this.book);
			}
			else
			{
				alert("자신의 단어장에만 암기완료 기능을 사용할 수 있습니다.\n \'내 단어장으로 스크랩\'기능을 사용해주세요.");
			}
		}
		else
		{
			alert('암기 완료 기능을 사용하시려면, 로그인이 필요합니다.');
		}
	},
	
	deleteVocabulary: function() {
		var is_playing = this.is_playing;
		if (is_playing)
			this.stop();
					
		var current_position = this.position;
		var index = this.index[current_position - 1];
		var viid = vocabularies[index][3]; // viid
				
		this.index = this.index.without(index);
		this.card_index = this.card_index.without(index);
		if (this.voca_index)
			this.voca_index = this.voca_index.without(index);
		if (this.quiz.question_index)
			this.quiz.question_index = this.quiz.question_index.without(index);
		
		this.update(current_position);
		if (is_playing)
			this.play();
		this.sound();
		
		return viid;
	},
	
	resize: function() {
		this.updateView();
	},
	
	setMode: function(mode) {
		if (mode != 'quiz' && this.quiz.quiz_started && !confirm('퀴즈가 진행 중입니다. 종료하시겠습니까?'))
			return;
		
		this.mode = mode;

		if (!this.is_data_loaded && mode != 'player')
			return;

		this.updateButtonPosition();
		this.updateControls();
		
		switch (mode)
		{
		case 'player':
			document.body.style.background = this.background ? this.background : '';
			this.initShortcut();
			this.quiz.stop();
			break;
			
		case 'quiz':
			document.body.style.background = '';
			this.stop();
			this.initShortcut();
			this.quiz.initStartPage();
			break;
			
		case 'config':
			document.body.style.background = '';
			this.stop();
			this.quiz.stop();
			this.initShortcut();
			break;
		}
	},
	
	updateControls: function() {
		switch (this.mode)
		{
		case 'player':
			$('player_button').addClassName('selected');
			$('quiz_button').removeClassName('selected');
			$('config_button').removeClassName('selected');
			
			$('timer_ctrl', 'position_ctrl', 'player_ctrl', 'view', 'mini_button', 'font_big_button', 'font_small_button').invoke('show');
			$('quiz_position_ctrl', 'quiz_ctrl', 'quiz', 'settings', 'config_ctrl').invoke('hide');
			if (this.sound_plugin != null)
				$('sound_button').show();
			break;
		case 'quiz':
			$('player_button').removeClassName('selected');
			$('quiz_button').addClassName('selected');
			$('config_button').removeClassName('selected');
			
			$('quiz_position_ctrl', 'quiz_ctrl', 'quiz').invoke('show');
			$('timer_ctrl', 'position_ctrl', 'player_ctrl', 'view', 'mini_button', 'font_big_button', 'font_small_button', 'settings', 'config_ctrl').invoke('hide');
			if (this.sound_plugin != null)
				$('sound_button').hide();
			break;
		case 'config':
			$('player_button').removeClassName('selected');
			$('quiz_button').removeClassName('selected');
			$('config_button').addClassName('selected');
			
			$('settings', 'config_ctrl').invoke('show');
			$('timer_ctrl', 'position_ctrl', 'player_ctrl', 'view', 'mini_button', 'font_big_button', 'font_small_button', 'quiz_position_ctrl', 'quiz_ctrl', 'quiz').invoke('hide');
			if (this.sound_plugin != null)
				$('sound_button').hide();
			break;
		}
		
		this.updateView();
	}, 
	
	toggleMini: function() {
		if (!this.mini_mode)
		{
			this.mini_mode = true;
			$('header', 'footer').invoke('hide');
			$('mini_button').style.top = '5px';
			$('sound_button').style.top = '25px';
			$('font_big_button').style.top = '-100px';
			$('font_small_button').style.top = '-100px';
			this.example_recovery = this.example_visible;
			this.toggleExample(false);
			window_resize(230, 70);
		}
		else
		{
			this.mini_mode = false;
			$('header', 'footer').invoke('show');
			this.updateButtonPosition();
			this.toggleExample(this.example_recovery);
			window_resize(315, 165);
		}
	},
	
	increaseFontSize: function() {
		if (this.mode == 'quiz')
		{
			this.quiz.increaseFontSize();
			return;
		}
		
		this.font_size *= 1.2
		this.updateFontSize();
		this.updateView();
	},
	
	decreaseFontSize: function() {
		if (this.mode == 'quiz')
		{
			this.quiz.decreaseFontSize();
			return;
		}
		
		this.font_size /= 1.2
		this.updateFontSize();
		this.updateView();
	},
	
	updateFontSize: function() {
		var name_font_size = this.name_style.size * this.font_size;
		var mean_font_size = this.mean_style.size * this.font_size;
		var example_font_size = this.example_style.size * this.font_size;
		$$('#content div.name').each(function(item) { item.style.lineHeight = name_font_size * 1.4 + 'pt', item.style.fontSize = name_font_size + 'pt'; });
		$$('#content div.mean').each(function(item) { item.style.lineHeight = mean_font_size * 1.4 + 'pt', item.style.fontSize = mean_font_size + 'pt'; });
		$$('#content div.example').each(function(item) { item.style.lineHeight = example_font_size * 1.4 + 'pt', item.style.fontSize = example_font_size + 'pt'; });
	},
	
	setSkin: function(color) {
		var skin_list = {'#C11B17': '01', '#CCCCCC': '02', '#6D7B8D': '03', '#806D7E': '04', '#15317E': '05', '#3090C7': '06', '#8467D7': '07', '#C12267': '08', '#810541': '09', '#C25A7C': '10', '#B93B8F': '11', '#437C17': '12', '#FFA500': '13', '#827839': '14'};
		var skin = skin_list[color] != undefined ? skin_list[color] : '01';
		$('skin_css').href = '/css/skin/skin_' + skin + '.css';
		$('PlayerSettingPlayerColor').value = color;
	},
	
	setQuizCount: function(count) {
		this.quiz.count = count;
		$('PlayerSettingQuizCount').value = count;
	},
	
	setDelayTime: function(time) {
		this.delay_time = time;
		$('PlayerSettingDelayTime').value = time;
	},
	
	setAutoStart: function(start) {
		$('PlayerSettingAutoStart').checked = start;
	},
	
	updateLearningLog: function(asynchronous) {
		if (!this.learning_log.date)
			return;
		
		var learning_log = this.learning_log;
		new Ajax.Request(
			'/player/save_learning_log',
			{
				parameters: {'LearningLogDate': learning_log.date, 'LearningLogContent': learning_log.log.join(',')},
				requestHeaders: {Accept: 'application/json'},
				onSuccess: function(request)
				{
					var date = request.responseText;
					if (date)
						player.initLearningLog(date); 
				}
			}
		);
	},
	
	startQuiz: function(quiz_count, quiz_type, user) {
		if (isNaN(parseInt(quiz_count)))
		{
			alert('퀴즈 개수를 입력해주세요.');
			return;
		}
		
		if (!user && quiz_count > 10)
		{
			alert('10개 이상의 퀴즈를 사용하시려면, 로그인이 필요합니다.')
			return;
		}
		
		this.quiz.count = quiz_count;
		this.quiz.type = quiz_type;
		this.quiz.start();
	},
	
	initShortcut: function() {
		this.clearShortcut();
		
		switch (this.mode)
		{
		case 'player':
			this.shortcut.add('Space', function(){ player.doPlayPause(); });
			this.shortcut.add(',', function(){ player.previous(); });
			this.shortcut.add('Left', function(){ player.previous(); });
			this.shortcut.add('.', function(){ player.next(); });
			this.shortcut.add('Right', function(){ player.next(); });
			
			this.shortcut.add('1', function(){ player.toggleName(); });
			this.shortcut.add('num1', function(){ player.toggleName(); });
			
			this.shortcut.add('2', function(){ player.toggleMean(); });
			this.shortcut.add('num2', function(){ player.toggleMean(); });
			
			this.shortcut.add('3', function(){ player.toggleExample(); });
			this.shortcut.add('num3', function(){ player.toggleExample(); });
			
			this.shortcut.add('4', function() {
				var visible = false;
				if (!player.mean_visible && !player.example_visible)
					visible = true;
				player.toggleMean(visible);
				player.toggleExample(visible);
			});
			this.shortcut.add('num4', function() {
				var visible = false;
				if (!player.mean_visible && !player.example_visible)
					visible = true;
				player.toggleMean(visible);
				player.toggleExample(visible);
			});
			
			this.shortcut.add('0', function(){ player.complete(); });
			this.shortcut.add('num0', function(){ player.complete(); });
			
			this.shortcut.add('Ctrl+Up', function(){ player.increaseFontSize(); });
			this.shortcut.add('Ctrl+Down', function(){ player.decreaseFontSize(); });
			
			this.shortcut.add('P', function(){ player.sound(true); });
			break;
			
		case 'quiz':
			if (this.quiz.quiz_started)
			{
				this.shortcut.add('1', function(){ player.quiz.check(0); });
				this.shortcut.add('num1', function(){ player.quiz.check(0); });
				this.shortcut.add('2', function(){ player.quiz.check(1); });
				this.shortcut.add('num2', function(){ player.quiz.check(1); });
				this.shortcut.add('3', function(){ player.quiz.check(2); });
				this.shortcut.add('num3', function(){ player.quiz.check(2); });
				this.shortcut.add('4', function(){ player.quiz.check(3); });
				this.shortcut.add('num4', function(){ player.quiz.check(3); });
				this.shortcut.add('Space', function(){ player.quiz.check(); });
				this.shortcut.add('Ctrl+Up', function(){ player.quiz.increaseFontSize(); });
				this.shortcut.add('Ctrl+Down', function(){ player.quiz.decreaseFontSize(); });
			}
			break;
		}
	},
	
	clearShortcut: function() {
		this.shortcut.remove('Space');
		this.shortcut.remove(',');
		this.shortcut.remove('Left');
		this.shortcut.remove('.');
		this.shortcut.remove('Right');
		this.shortcut.remove('1');
		this.shortcut.remove('num1');
		this.shortcut.remove('2');
		this.shortcut.remove('num2');
		this.shortcut.remove('3');
		this.shortcut.remove('num3');
		this.shortcut.remove('4');
		this.shortcut.remove('num4');
		this.shortcut.remove('0');
		this.shortcut.remove('num0');
		this.shortcut.remove('Ctrl+Up');
		this.shortcut.remove('Ctrl+Down');
		this.shortcut.remove('P');
	}
});

var Quiz = Class.create({
	initialize: function(player) {
		this.player = player;
		this.question_index = null;
		this.count = 10;
		this.quiz_started = false;
		this.font_size = 9;
		this.type = 1;
	},
	
	initView: function() {
		$('quiz_start').hide();
		$('font_big_button', 'font_small_button').invoke('show');
		$('quiz_data').update('');
		this.current_div = new Element('div').addClassName('notice').update('퀴즈 데이터를 준비하는 중');
		$('quiz_data').appendChild(this.current_div);
		$('quiz_data').show();
	},
	
	initStartPage: function() {
		if (!this.question_index)
		{
			this.question_index = this.player.getVocaIndex().reject(function(idx) {
				return vocabularies[idx][1].length == 0; // mean
			});
		}
		if (this.question_index.length <= 0)
		{
			$('quiz_start').update('');
			this.current_div = new Element('div').addClassName('notice').update('퀴즈에서 사용할 단어가 존재하지 않습니다.');
			$('quiz_start').appendChild(this.current_div);
		}
	},
	
	createQuiz: function(count) {
		this.question_index.sort(function(a, b) {
			return Math.floor(Math.random() * 3) - 1;
		});
		
		if (count > this.question_index.length)
			count = this.question_index.length;
		
		this.answers = new Array();
		for (var i = 0; i < count; ++i)
		{
			var question_idx = this.question_index[i];
			var answer_index = this.question_index.reject(function(idx) {
				return vocabularies[question_idx][0] == vocabularies[idx][0] || vocabularies[question_idx][1] == vocabularies[idx][1];
			});	
			
			this.answers.push(this.createAnswers(question_idx, answer_index));
		}
		return count;
	},
	
	createAnswers: function(question_idx, answer_index) {
		answer_index = answer_index.sort(function(a, b) {
			return Math.floor(Math.random() * 3) - 1;
		});
		
		var temp_answer_index = new Array();
		var cnt = 0;
		var index = 0;
		
		while (cnt++ < 3)
		{
			if (answer_index[0] == undefined)
				break;
			
			temp_answer_index.push(answer_index[0]);
				
			answer_index = answer_index.reject(function (idx) {
				return (vocabularies[answer_index[0]][0] == vocabularies[idx][0] || vocabularies[answer_index[0]][1] == vocabularies[idx][1]);
			});
		}
				
		answer_index = temp_answer_index;
		answer_index.push(question_idx);
		
		var idx = Math.floor(Math.random() * answer_index.length);
		var temp = answer_index[idx];
		answer_index[idx] = question_idx;
		answer_index[answer_index.length - 1] = temp;
		
		return answer_index;
	},
	
	start: function() {
		this.initView();
		
		this.quiz_position = 0;
		this.quiz_result = new Array();
		
		this.quiz_count = this.createQuiz(this.count);
		this.quiz_started = true;
		
		this.player.initShortcut();
		
		this.update(this.quiz_position);
	},
	
	stop: function() {
		if (!this.quiz_started)
			return;
		
		this.quiz_started = false;
		$('quiz_ctrl').update('');
		$('quiz_data').update('');
		$('quiz_data').hide();
		$('quiz_start').show();
		this.player.updateView();
		
		this.player.initShortcut();
	},
	
	update: function(index) {
		this.current_div.remove();
		
		$('quiz_data').removeClassName('correct_answer');
		$('quiz_data').removeClassName('wrong_answer');
		
		this.current_div = this.createQuestionDiv(index);
		$('quiz_data').appendChild(this.current_div);
		this.updateFontSize();
		
		$('quiz_ctrl').update('<a href="javascript:;" onclick="player.quiz.check(); return false;" id="quiz_mark_button" class="button" title="정답 확인"><span>정답 확인</span></a>');
		
		$('quiz_position').update('' + (index + 1) + ' / ' + this.quiz_count);
		
		this.quiz_position = index;
		
		this.player.updateView();
	},
	
	createQuestionDiv: function(index) {
		var quiz_div = new Element('div', {'id': 'question_' + index}).addClassName('question');
		var vocabulary_question = (this.type == 1) ? vocabularies[this.question_index[index]][0] : vocabularies[this.question_index[index]][1];
		quiz_div.appendChild(new Element('div', {'name': 'vocabulary'}).update(vocabulary_question)); // name
		var answers_div = new Element('div').addClassName('answers');
		
		var answers_html = '';
		for (var i = 0; i < this.answers[index].length; ++i)
		{
			var vocabulary_answer = (this.type == 1) ? vocabularies[this.answers[index][i]][1] : vocabularies[this.answers[index][i]][0];

			answers_html += '<a id="answer' + index + '_' + i + '" href="javascript:;" class="answer" onclick="player.quiz.check(' + i + '); return false;" onfocus="this.blur();">' + (i + 1) + '. ' + vocabulary_answer + '</a>'; // mean
		}
		answers_div.update(answers_html);
		
		quiz_div.appendChild(answers_div);
		
		return quiz_div;
	},
	
	check: function(answer) {
		if (!this.quiz_started)
			return;
		
		var index = this.quiz_position;
		
		if (this.quiz_result[index] != undefined)
		{
			if (this.quiz_position > this.quiz_count - 2)
				this.score();
			else
				this.next();
			return;
		}
		
		this.quiz_result[index] = false;
		
		if (answer != undefined && answer < this.answers[index].length)
		{
			if (this.question_index[index] == this.answers[index][answer]) // correct answer
			{
				this.quiz_result[index] = true;
				$('quiz_data').addClassName('correct_answer');
			}
			else // wrong answer
			{
				$('quiz_data').addClassName('wrong_answer');
				$('answer' + index + '_' + answer).addClassName('wrong');
			}
		}
		else
		{
			$('quiz_data').addClassName('wrong_answer');
		}
		
		for (var i = 0; i < this.answers[index].length; ++i)
		{
			if (this.question_index[index] == this.answers[index][i])
			{
				$('answer' + index + '_' + i).addClassName('correct');
				break;
			}
		}
		
		if (this.quiz_position > this.quiz_count - 2)
			$('quiz_ctrl').update('<a href="javascript:;" onclick="player.quiz.score(); return false;" id="quiz_result_button" title="결과 보기" class="button"><span>결과 보기</span></a>');
		else
			$('quiz_ctrl').update('<a href="javascript:;" onclick="player.quiz.next(); return false;" id="quiz_next_button" title="다음 문제" class="button"><span>다음 문제</span></a>');
	},
	
	next: function() {
		this.update(this.quiz_position + 1);
	},
	
	score: function() {
		var correct_count = 0;
		for (var i = 0; i < this.quiz_result.length; ++i)
		{
			if (this.quiz_result[i] == true)
				++correct_count;
		}

		$('quiz_data').update('');
		$('quiz_data').removeClassName('correct_answer');
		$('quiz_data').removeClassName('wrong_answer');
		
		$('quiz_data').appendChild(new Element('div').addClassName('result').update(this.quiz_count + '문제 중에 ' + correct_count + '문제를 맞추셨습니다.'));
		this.player.updateView();
		
		$('quiz_ctrl').update('<a href="javascript:;" onclick="player.quiz.stop(); return false;" id="quiz_stop_button" title="퀴즈종료" class="button"><span>퀴즈종료</span></a>');
	},
	
	increaseFontSize: function() {
		this.font_size *= 1.2
		this.updateFontSize();
		this.player.updateView();
	},
	
	decreaseFontSize: function() {
		this.font_size /= 1.2
		this.updateFontSize();
		this.player.updateView();
	},
	
	updateFontSize: function() {
		var font_size = this.font_size;
		$$('#content div.question').each(function(item) { updateFontSize(item, font_size * 1.5, font_size * 2.5); });
		$$('#content a.answer').each(function(item) { updateFontSize(item, font_size, font_size * 1.5); });
	}
});

var frame_width, frame_height;

function window_resize(width, height)
{
	var calculate = function(width, height) {
		try {
			if (navigator.appName == "Netscape")
			{
				top.outerWidth = width;
				top.outerHeight = height;
			}
			else
			{
				top.resizeTo(width, height);
			}
		} catch (e) {
		}
	};
	
	if (parseInt(navigator.appVersion) > 3)
	{
		if (frame_width == undefined || frame_height == undefined)
		{
			calculate(250, 100);
			frame_width = 250 - document.viewport.getWidth();
			frame_height = 100 - document.viewport.getHeight();
			window_resize(width, height);
			return;
		}
		else
		{
			calculate(width + frame_width, height + frame_height);
		}
	}
}

function setCookie(c_name, value, expiredays)
{
	var exdate = new Date();
	exdate.setDate(exdate.getDate() + expiredays);
	document.cookie = c_name + "=" + escape(value) + ((expiredays == null) ? "" : ";expires=" + exdate.toGMTString());
}

function getCookie(c_name)
{
	if (document.cookie.length > 0)
	{
		c_start = document.cookie.indexOf(c_name + "=");
		if (c_start != -1)
		{ 
			c_start = c_start + c_name.length + 1; 
			c_end = document.cookie.indexOf(";", c_start);
			if (c_end == -1)
				c_end = document.cookie.length;
			return unescape(document.cookie.substring(c_start, c_end));
		} 
	}
	return "";
}

function updateFontSize(item, font_size, line_height)
{
	item.style.lineHeight = line_height + 'pt';
	item.style.fontSize = font_size + 'pt';
}

function updateStyle(item, style, font_size)
{
	if (style.background)
		item.style.background = style.background;
	if (style.font)
		item.style.fontFamily = style.font;
	if (style.color)
		item.style.color = style.color;
	if (style.size)
	{
		var size = style.size * font_size;
		item.style.lineHeight = size * 1.4 + 'pt';
		item.style.fontSize = size + 'pt';
	}
	if (style.bold)
		item.style.fontWeight = 'bold';
	if (style.italic)
		item.style.fontStyle = 'italic';
}

function setStyleArray(style, background, font, color, size, ext)
{
	if (background)
		style['background'] = background;
	if (font)
		style['font'] = font;
	if (color)
		style['color'] = color;
	if (size)
		style['size'] = size;
	if (ext)
		style['bold'] = (ext.indexOf('b') >= 0);
	if (ext)
		style['italic'] = (ext.indexOf('i') >= 0);

	return style;
}

function playSound(type, url) 
{
	var pe = new PeriodicalExecuter(function() {
		switch (type)
		{
		default:
		case 'mp3':
			try {
				codebase = Prototype.Browser.IE ? 'codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" ' : '';
				$('WordbreakMp3PlayerDiv').update(' \
					<object id="WordbreakMp3Player" type="application/x-shockwave-flash" data="/swf/wordbreak_mp3_player.swf" ' + codebase + 'width="0" height="0"> \
						<param name="movie" value="/swf/wordbreak_mp3_player.swf" /> \
						<param name="AllowScriptAccess" value="always" /> \
						<param name="FlashVars" value="mp3=' + url + '&autoplay=1" /> \
					</object> \
				');
			}
			catch(e) {
			}
			break;
			
		case 'wav':
			try {
				$('WordbreakWavPlayerDiv').update('<object type="audio/x-wav" data="' + url + '" width="0" height="0"><param name="src" value="' + url + '"><param name="autoplay" value="true"><param name="autoStart" value="1"></object>');
			}
			catch(e) {
			}
			break;
		}
		pe.stop();
	}, 0);
}