(function ($, win, doc) {
/**
* @fileoverview googleSiteSearchAPI との 通信、結果表示を行うスクリプト
*
* @description 概要としては、form要素のjQuery.data領域に検索キーワード<br>
* や、現在のページ番号を保持しており、この値を変更する処理と、この値を使って<br>
* APIに検索結果のリクエストを行う処理がある。という構成になっています。<br><br>
*
* 要素をクリックした際の各種イベント、onXXXXXXメソッドの類が値の書き換え。<br>
* 書き換えた後に呼ばれるgetResultが検索結果のリクエストを開始。<br>
* リクエスト成功時のコールバック、updateResultメソッドによって画面の更新。<br>
* という流れです。
*/

var $form = null,
	$form_input =  null,
	$form_submit =  null,
	$form_reset =  null,
	$form_tab = null,
	$form_paging = null,
	$header_form = null,
	$header_form_input =  null,
	$header_form_submit =  null,
	$result = null,
	$result_title = null,
	$result_meta = null,
	$result_keyword = null,
	$result_amount = null,
	$result_start = null,
	$result_end = null,
	$tmpl_cassetteCase = null,
	$tmpl_cassette = null,
	$tmpl_cassetteTitle = null,
	$tmpl_cassetteDescription = null,
	$tmpl_cassettePath = null,
	$tmpl_paging = null,
	$tmpl_paging_ul = null,
	$tmpl_paging_back = null,
	$tmpl_paging_num = null,
	$tmpl_paging_next = null,
	$tmpl_loading = null,
	selector_tmpl_cassetteTitle = '#js-cse-result-cassette-title',
	selector_tmpl_cassetteDescription = '#js-cse-result-cassette-description',
	selector_tmpl_cassettePath = '#js-cse-result-cassette-domain',
	searchKeyword = location.search.match(/uri=([^&]*)/) ? decodeURI(location.search.match(/uri=([^&]*)/)[1]) : null,
	$currentTab = null;

/* DOM Content Loaded ********************************************************/

$(win).bind('load', function () {

	$form = $('#js-cse-form'),
	$form_input =  $('#js-cse-form-input'),
	$form_submit =  $('#js-cse-form-submit'),
	$form_reset =  $('#js-cse-form-reset'),
	$form_tab = $('#js-cse-form-tab'),
	$form_paging = $('#js-cse-form-paging'),
	$header_form = $('.srcGglFm'),
	$header_form_input =  $('.headInp'),
	$header_form_submit =  $('.headBtn'),
	$result = $('#js-cse-result'),
	$result_title = $('#js-cse-result-title'),
	$result_meta = $('#js-cse-result-meta'),
	$result_keyword = $('#js-cse-result-keyword'),
	$result_amount = $('#js-cse-result-amount'),
	$result_start = $('#js-cse-result-start'),
	$result_end = $('#js-cse-result-end'),
	$tmpl_cassetteCase = $('#js-cse-result-cassetteCase'),
	$tmpl_cassette = $('#js-cse-result-cassette'),
	$tmpl_cassetteTitle = $('#js-cse-result-cassette-title'),
	$tmpl_cassetteDescription = $('#js-cse-result-cassette-description'),
	$tmpl_cassettePath = $('#js-cse-result-cassette-domain'),
	$tmpl_paging_ul = $('#js-cse-form-paging-ul');
	$tmpl_paging_back = $('#js-cse-form-paging-back'),
	$tmpl_paging_num = $('#js-cse-form-paging-num'),
	$tmpl_paging_next = $('#js-cse-form-paging-next'),
	$tmpl_loading = $('#js-cse-load'),

	//console.group('DOM初期補足チェック');
	//console.log($form);
	//console.log($form_input);
	//console.log($form_submit);
	//console.log($form_reset);
	//console.log($result);
	//console.log($result_keyword);
	//console.log($result_amount);
	//console.log($result_start);
	//console.log($result_end);
	//console.log($form_tab);
	//console.log($result_cassetteCase),
	//console.log($tmpl_cassette);
	//console.log($tmpl_cassetteTitle);
	//console.log($tmpl_cassetteDescription);
	//console.log($tmpl_cassettePath);
	//console.groupEnd('DOM初期補足チェック');

	// タブ押下時のイベント登録
	$form_tab.bind('click', onClickTab);

	// リクエスト成功時のイベント登録
	$form_paging.bind('click', onChangePage);

	// リクエスト送信、受信成功時のイベント登録
	$form
		.data('start', 0)
		.data('filter', 1)
		.bind('submit', onSubmitSearch)
		.bind('success', updateResult);

	// フォームリセットイベント登録
	$form_reset.bind('click', function (e) {
		$form_input.val('');
		return false;
	});

	// ヘッダーフォームイベント
	$header_form.unbind('submit');
	$header_form_submit.unbind('click');
	$header_form.submit(function (e) {
		if (!$header_form_input.val()) { return false; }
		$form_input.val($header_form_input.val());
		$form.trigger('submit');
		return false;
	});

	// URLパラメータに検索語句があれば検索開始
	if (searchKeyword) {
		
		$form_input.val(searchKeyword);
		$form.trigger('submit');
	}
});

/* Functions *****************************************************************/

/**
* @function
* @description 検索ボタン押下時のイベント<br>
* 検索ボックスに入っているキーワードをform要素のjQuery.data領域に格納。<br>
* デフォルトの絞り込みを行うため、最後は当該タブのクリックイベントを起こす<br>
* ことで検索結果リクエストを行う。
*/
function onSubmitSearch (e) {

	var q = $form_input.val().replace(/\s/g, '+'),
		start = 0,
		filter = 0;

	if (!q) { return false; }

	$header_form_input.val($form_input.val());

	$form
		.data('q', q)
		.data('start', start)
		.data('filter', filter);

	$form_tab.find('li').each(function (e) {
		$(this).data('state', start).data('filter', filter);
	});

	if ($currentTab && $currentTab.size() !== 0) {
		$currentTab.removeClass('current')
	}

	//$form_tab.find('a:first').trigger('click');
	var new_q = q + '+more:住友林業クレストサイトのみ';
	getResult(new_q, start, filter);

	return false;
}

/**
* @function onChangePage
* @description ページ変更のハンドリング
*/
function onChangePage (e) {

	var $el = $(e.target).closest('a'),
		$li = $el.closest('li'),
		num = $el.text() - 1,
		start = parseInt($form.data('start'), 10);

	if (!$el.size()) { return false; }
	if ($li.hasClass('disable') || $li.hasClass('current')) { return false; }

	// 「次へ・前へ」か「数値」かを判定
	if (!$li.hasClass('pagenate')) {
		num = num ? num * 10 : 0;
		getResult(null, num);
	} else {
		if (!$li.prev().size()) {
			// 「前へ」のとき
			getResult(null, start - 10);
		} else if (!$li.next().size()) {
			// 「次へ」のとき
			getResult(null, start + 10);
		}
	}

	win.location.hash = 'js-cse-result-title'

	return false;
}

/**
* @function
* @description form要素に格納中の検索キーワードを以って絞り込みを行う。<br>
* ページ番号は0としています
*/
function onClickTab (e) {

	var $el = $(e.target).closest('a'),
		$li = $el.closest('li'),
		// $form.data('q')に格納されたキーワードを優先取得。絞り込みの more:*** は既存があれば消しておきます。
		q = $form.data('q') ? $form.data('q').replace(/\+more.*/, '') : $form_input.val(),
		// 押されたタブの絞り込み条件 more:*** を改めて取得
		more = $el.text(),
		// 絞り込みキーワードを足して実際にAPIに投げる文を組み立てます
		new_q = q + '+more:' + more,
		// 要素に保持されたページ番号があれば取得。なければ0。
		state = $li.data('state') ? $li.data('state') : 0,
		filter = !isNaN($li.data('filter')) ? $li.data('filter') : 1;

	if ($el.size() === 0 && $li.size() === 0) { return false; }
	if ($li.hasClass('current')) { return false; }

	// カレントタブは現在のページ番号を保持させてカレントをOFF
	if ($currentTab && $currentTab.size() !== 0) {
		$currentTab
			.data('state', $form.data('start'))
			.data('filter', $form.data('filter'))
			.removeClass('current')
	}

	// 押されたタブをカレント表示
	$li.addClass('current');

	getResult(new_q, state, filter);

	$currentTab = $li;

	return false;
}

/**
* @function
* @description 引数か、form要素のjQuery.data領域に格納された検索内容で<br>
* リクエストを行う。引数の内容を優先し、無い場合はjQuery.dataを用いる。<br><br>
*
* Ajaxによるリクエストの結果タイミングはform要素のカスタムイベントで、<br>
* jQuery.Ajaxのstatusメッセージと同じイベント名で配信が行われる。
*/
function getResult (q, start, filter) {

	var q = q || $form.data('q'),
		start = !isNaN(start) ? start : $form.data('start'),
		filter = !isNaN(filter) ? filter : $form.data('filter'),
		data = null;

	$form
		.data('q', q)
		.data('start', start)
		.data('filter', filter);

	data = $.param({
		q: q,
		start: start,
		filter: filter
	});

	$.ajax({
		type: 'GET',
		url: '/common/googleSiteSearchAPI.php',
		data: data,
		beforeSend: showLoading,
		complete: function (req, status) {
			if (status === 'success') {
				$form.trigger('success', [req.responseXML]);
			} else if (status === 'error') {
			} else if (status === 'timeout') {
			} else if (status === 'parsererror') {
			}
		}
	});
}

/**
* @function
* @description Ajax通信の結果得られたXMLの内容をHTMLに書き出します。
*/
function updateResult (e, xml) {

	var $xml = $(xml),
		$cassetteCase = null,
		$cassette = null,
		$cassetteTitle = null,
		$cassetteDescription = null,
		$cassettePath = null,
		$nodeList = $xml.find('R'),
		$node = null,
		xml_title = null,
		xml_url = null,
		xml_description = null,
		xml_domain = null,
		xml_mime = null,
		xml_start = $xml.find('PARAM[name=start]').attr('value') || 0;

	$result_title.attr('style', 'display: block !important');
	$('#searchWrap').attr('style', 'display: block !important');
	//$result_meta.attr('style', 'display: block !important');

	$result_keyword.text('"' + $xml.find('Q').text().replace(/\smore.*/, '') + '"');
	$result_amount.text($xml.find('RES').find('M').text() || 0);
	$result_start.text($xml.find('RES').attr('SN'));
	$result_end.text($xml.find('RES').attr('EN'));

	if (!$nodeList.size()) {
		showEmptyResult($xml);
		return false;
	}

	$result.empty();
	$cassetteCase = $tmpl_cassetteCase.clone().removeAttr('id');

	$nodeList.each(function (i) {

		$node = $(this);

		// HTMLに埋め込んだテンプレートをclone. idは重複をさけるため剥奪
		$cassette = $tmpl_cassette.clone().removeAttr('id');
		$cassetteTitle = $cassette.find(selector_tmpl_cassetteTitle).removeAttr('id');
		$cassetteDescription = $cassette.find(selector_tmpl_cassetteDescription).removeAttr('id');
		$cassettePath = $cassette.find(selector_tmpl_cassettePath).removeAttr('id');

		// XMLからテキストデータを取得
		xml_title = $node.find('T').text();
		xml_url = $node.find('U').text();
		xml_description = $node.find('S').text();
		xml_mime = $node.attr('MIME') || null;

		// テキストデータを加工
		xml_title = xml_title.replace(/(<|<\/)(b)>/g, '$1em>');
		xml_description = xml_description.replace(/(<|<\/)(b)>/g, '$1em>');
		xml_description = xml_description.replace(/<br>/g, '');
		xml_domain = xml_url.replace(/htt(p|ps):\/\//, '');

		if (xml_mime) {
			if (xml_mime === 'application/pdf') {
				xml_title = '[PDF]' + xml_title;
			}
			if (xml_mime === 'application/vnd.ms-excel') {
				xml_title = '[XLS]' + xml_title;
			}
		}

		//console.group('cloneしたカセットのDOM補足チェック');
		//console.log($node);
		//console.log($cassette);
		//console.log($cassetteTitle);
		//console.log($cassetteDescription);
		//console.log($cassettePath);
		//console.groupEnd('cloneしたカセットのDOM補足チェック');

		//console.group('XML値チェック');
		//console.log(xml_title);
		//console.log(xml_url);
		//console.log(xml_description);
		//console.log(xml_domain);
		//console.log(xml_start);
		//console.groupEnd('XML値チェック');

		// ページタイトルの差し込み
		/*if (/sfc\.jp/.test(xml_domain)) {
			$cassetteTitle
				.attr('href', xml_url)
				.html(xml_title);
		} else {
			$cassetteTitle
				.attr({
					'href': xml_url,
					'target': '_blank'
				})
				.html(xml_title + '<img width="13" height="11" class="searchIcnBlank" alt="" src="/common/image/foot_icn_blank.gif">');
		}*/
		$cassetteTitle
				.attr('href', xml_url)
				.html(xml_title);
				

		// ページ説明文の差し込み
		$cassetteDescription.html(xml_description);

		// パス欄の差し込み
		$cassettePath.text(xml_domain);

		// 出来上がった検索結果カセットを差し込み
		$cassetteCase.append($cassette);
	});

	// 検索結果一覧の差し込み
	$result.append($cassetteCase);

	if ($xml.find('RES').find('FI').size() !== 0 && $xml.find('RES').find('XT').size() !== 0) {
		// オートフィルタON かつ 検索結果の除外が発生した場合
		// フィルターをOFFにして再検索をする案内を表示
		//showFilter($xml);
	}

	// ページングの更新
	updatePaging($xml);
}

/**
* ページング部分の画面更新
*/
function updatePaging ($xml) {

	var $paging_ul = $tmpl_paging_ul.clone().removeAttr('id'),
		$paging_back = $tmpl_paging_back.clone().removeAttr('id'),
		$paging_num = $tmpl_paging_num.clone().removeAttr('id'),
		$paging_next = $tmpl_paging_next.clone().removeAttr('id'),
		total = $xml.find('RES').find('M').text(),
		start = Math.min($form.data('start'), Math.floor(total / 10) * 10),
		currentPage = start !== 0 ? start / 10 + 1 : 1,
		amount = Math.min(10, $xml.find('RES').find('M').text() / 10),
		i = currentPage,
		j = amount / 2,
		ii = 0;

	$form.data('start', start);

	if (Math.floor(total / 10) * 10 === start) {
		j = 9;
	}

	while (j--) {
		if (i === 1) { break; }
		i--;
	}

	$paging_ul.empty();

	for (; ii < amount; ++ii) {
		$paging_ul.append($paging_num.clone().find('a').text(i).end());
		i++;
	}

	$paging_ul
		.append($paging_next)
		.prepend($paging_back);

	$form_paging
		.empty()
		.append($paging_ul);

	$form_paging.find('a').each(function (i) {

		var $el = $(this),
			$li = $el.closest('li');

		if (parseInt($el.text(), 10) === currentPage) {
			$li.addClass('current')
				.prev('.pagenate').addClass('disable')
				.end().next('.pagenate').addClass('disable');
		} else {
			$li.removeClass('current')
				.prev('.pagenate').removeClass('disable')
				.end().next('.pagenate').removeClass('disable');
		}
	});
}

/**
* @function
* @description ローディング中画面を表示
*/
function showLoading () {
	$result
		.empty()
		.append($tmpl_loading.clone().removeAttr('id'));
}

/**
* @function
* @description 結果0件の表示
*/
function showEmptyResult ($xml) {
	var $empty = $('#js-cse-zero').clone().removeAttr('id'),
		$q = $empty.find('#js-cse-zero-q')
			.removeAttr('id')
			.text($xml.find('Q').text().replace(/\smore.*/, '')),
		$p = $result_meta.find('p');

	$result
		.empty()
		.append($empty);
}

/**
* @function
* @description 除外フィルターの表示
*/
function showFilter ($xml) {
	var $filter = $('#js-cse-filter').clone().removeAttr('id'),
		$amount = $filter.find('#js-cse-filter-amount')
			.removeAttr('id')
			.text($xml.find('RES').find('M').text()),
		$anchor = $filter.find('#js-cse-filter-a');

	$anchor.bind('click', function (e) {
		getResult(null, $form.data('start'), 0);
		return false;
	});

	$result.append($filter);
}



})(jQuery, window, document);

