#!/usr/local/bin/perl
#***************************************************************************#,
#
#	プロジェクト名	：	マグライト
#	案件名			：	取り扱い店舗検索
#	処理概要		：	マッチする都道府県、区市町村、キーワードで
#						取り扱い店舗マップを表示
#	作成日 / 作成者	：	2002/08/05 / 神戸直樹
#	更新日 / 作成者	：	2002/09/02 / 神戸直樹 店舗データの新旧を区別する
#
#***************************************************************************#,
require "jcode.pl";
require "map-libra.pl";
#***************************************************************************#
#	Configure
#***************************************************************************#
# デバッグモード true:1 false:0
$DEBUG_MODE = 1;

# CSVファイル格納ディレクトリ
$csv_dir = './map_data';

# 静的ドキュメントルート
# $doc_root = '/map';

# 区市町村別リスト表示テンプレート
$templ_city = './_templ_city.html';

# 地図一覧表示テンプレート
$templ_result = './_templ_result.html';

# 地図&区市町村の一覧のタグ
$html_result_list = '';

# 前、次ページリンクおよび総検索結果ページへのリンクを含んだタグ
$html_result_link = '';

# 検索結果のメッセージ
$html_result_msg = '';

# CSVファイルのカラム名と番号(from zero)の対応
%csv_col_name = (
	"rec_id" => 0,	# レコードID
	"city_prefix" => 1,	# 市区町村名のひらがな
	"city_name" => 2,	# 市区町村名(漢字)
	"store" => 3,	# 店舗名
	"address" => 4,	# 住所
	"telephone" => 5,	# 電話番号
	"map_url" => 6,	# 地図のURL
);

# 都道府県とコード対応
%prefec = (
	"01" => "北海道",
	"02" => "青森県",
	"03" => "岩手県",
	"04" => "宮城県",
	"05" => "秋田県",
	"06" => "山形県",
	"07" => "福島県",
	"08" => "茨城県",
	"09" => "栃木県",
	"10" => "群馬県",
	"11" => "埼玉県",
	"12" => "千葉県",
	"13" => "東京都",
	"14" => "神奈川県",
	"15" => "新潟県",
	"16" => "富山県",
	"17" => "石川県",
	"18" => "福井県",
	"19" => "山梨県",
	"20" => "長野県",
	"21" => "岐阜県",
	"22" => "静岡県",
	"23" => "愛知県",
	"24" => "三重県",
	"25" => "滋賀県",
	"26" => "京都府",
	"27" => "大阪府",
	"28" => "兵庫県",
	"29" => "奈良県",
	"30" => "和歌山県",
	"31" => "鳥取県",
	"32" => "島根県",
	"33" => "岡山県",
	"34" => "広島県",
	"35" => "山口県",
	"36" => "徳島県",
	"37" => "香川県",
	"38" => "愛媛県",
	"39" => "高知県",
	"40" => "福岡県",
	"41" => "佐賀県",
	"42" => "長崎県",
	"43" => "熊本県",
	"44" => "大分県",
	"45" => "宮崎県",
	"46" => "鹿児島県",
	"47" => "沖縄県",
);

# 検索結果$result_per_hit件ごとに表示する。(最大表示数)
$result_per_hit = 10;

# 他の検索結果ページへの表示リンクの数
$display_link_num = 10;

# フリーワードのNG文字
@str_ngwrd = (
#	'+',
#	'-',
#	'03',
);

# 50音のコード
%hiragana = (
	'あ' => '\xA4[\xA1-\xAA]',
	'か' => '\xA4[\xAB-\xB4]',
	'さ' => '\xA4[\xB5-\xBE]',
	'た' => '\xA4[\xBF-\xC9]',
	'な' => '\xA4[\xCA-\xCE]',
	'は' => '\xA4[\xCF-\xDD]',
	'ま' => '\xA4[\xDE-\xE2]',
	'や' => '\xA4[\xE3-\xE8]',
	'ら' => '\xA4[\xE9-\xED]',
	'わ' => '\xA4[\xEE-\xF3]',
	'？' => '[^\xA4]|\xA4[^\xA1-\xF3]',
);

# 確認用CSVデータの識別正規表現 for rec_id
$regex_checked_csv = '.';

#***************************************************************************#
#	Main Routine
#***************************************************************************#
&decode('sjis');

# 区市町村別の場合
if ($form{'p'} =~ /^\d\d$/ && $form{'c'})
{
	&city
}
# 都道府県別の場合
elsif ($form{'p'} =~ /^\d\d$/)
{
	&prefecture;
}
else
{
	&search;
}
exit;

#***************************************************************************#
#	関数名		：	city
#	処理概要	：	区市町村別に地図詳細結果表示（CSV読み込み）
#	パラメタ	：	なし
#	戻り値		：	なし
#***************************************************************************#
sub city
{
	my ($filename) = $csv_dir . '/' . $form{'p'} . '.csv';
	open(CITY,$filename)
		|| die "&city: Can not open $filename\n";
	seek(CITY,0,SEEK_SET);
	my (@arr);
	my (%hsh_csv_data);
	while(<CITY>)
	{
		s/\r\n$//g;
		s/\n$//g;
		s/\r$//g;
		@arr = split /,/, &jcode::euc($_, "sjis");

		# チェック済みのCSVデータがあった場合、排除する。
		if ($arr[$csv_col_name{rec_id}] =~ /$regex_checked_csv/)
		{
			# データをプッシュ
			push @{ $hsh_csv_data{$arr[$csv_col_name{city_prefix}]} },
				&jcode::euc($_, "sjis");
		}
	}


	&csv_to_html(
		@{ $hsh_csv_data{$form{c}} }
	);
}

#***************************************************************************#
#	関数名		：	prefecture
#	処理概要	：	都道府県別の検索結果表示
#	パラメタ	：	なし
#	戻り値		：	なし
#***************************************************************************#
sub prefecture
{
	# 接頭文字に順番を割り当てる(ソート処理用)
	my ($href);
	my ($role);

	# 都道府県ファイルオープン
	my ($filename) = $csv_dir . '/' . $form{'p'} . '.csv';
	open(PRF, $filename)
		or die "&prefecture: Can not open : $!: $filename";
	seek(PRF,0,SEEK_SET);
	my (@arr);
	my (%hsh_csv_data);
	while (<PRF>)
	{
		s/\r\n$//;
		s/\n$//;
		s/\r$//;
		@arr = split /,/, &jcode::euc($_, "sjis");

		# チェック済みのデータを読まないようにする。
		if ($arr[$csv_col_name{rec_id}] =~ /$regex_checked_csv/)
		{
			# 該当する接頭文字があるか検索し格納
			foreach $href (keys %hiragana)
			{
				if ($arr[$csv_col_name{city_prefix}] =~
					/^$hiragana{$href}/)
				{
					if (!exists
						$hsh_csv_data{$href}{
							$arr[$csv_col_name{city_prefix}]}
					)
					{
						$hsh_csv_data{$href}{$arr[$csv_col_name{city_prefix}]}
							= $arr[$csv_col_name{city_name}];
					}
					last;
				}
			}
		}
	}
	close(PRF);

	# 接頭文字でソート
	my (@arr_prefix) = sort { $a cmp $b } keys %hsh_csv_data;

	# HTMLタグを挿入
	my ($key_prefix);
	my ($c_uenc);
	foreach $key_prefix (0 .. $#arr_prefix)
	{
		$html_result_list .=
			"<div class=\"prefbox\"><h3>"
			. $arr_prefix[$key_prefix]
			. "</h3>\n";

		# 区市町村(ひらがな)でソート
		my (@arr_code) =
			sort { $a cmp $b } keys %{ $hsh_csv_data{
				$arr_prefix[$key_prefix]} };
		my ($key_code);
		foreach $key_code (0 .. $#arr_code)
		{
			if ($key_code== 0)
			{
				$html_result_list .= "<ul>";
			}

			# 区市町村名のURLエンコード
			$c_uenc = $arr_code[$key_code];
			&jcode::convert(\$c_uenc, 'sjis', 'euc');
			$c_uenc =~ s/([^\w])/"%" . unpack("H2", $1)/eg;
			$c_uenc =~ tr/ /+/;

			# リンクを作成
			$html_result_list .=
				qq(<li><a href=")
				. $ENV{'SCRIPT_NAME'} . '?' . $ENV{QUERY_STRING} . '&'
				. "c=$c_uenc";
			$html_result_list .=
				qq(">)
				. $hsh_csv_data{
					$arr_prefix[$key_prefix]}{$arr_code[$key_code]}
				. "</a></li>\n";

			# 最後に空のセルを挿入
			if ($key_code == $#arr_code)
			{
				my ($arrange) = ($#arr_code + 1) % 3;
				$arrange = $arrange ? 3 - $arrange : 0;
				for($i = 0; $i < $arrange; $i++)
				{
				}
			}

			if ($key_code == $#arr_code)
			{
				$html_result_list .= "</ul></div>";
			}
		}

		# 50音別の間にスペーサーの挿入
		if ($key_prefix < $#arr_prefix)
		{
			#$html_result_list .= '</div>';
		}
	}

	if (! $html_result_list)
	{
		$html_result_list = <<"EOM",
<div>該当する市区町村が見つかりませんでした。</div>
EOM
	}

	&display($templ_city);
}
#***************************************************************************#
#	関数名		：	search
#	処理概要	：	各単語の全件検索（CSV読み込み）
#	パラメタ	：	単語の配列
#	戻り値		：	CSV形式(string)
#***************************************************************************#
sub search
{
	# 全角スペースを半角スペースに変換
	my ($_str) = $form{'q'};
	&jcode::tr(\$_str, '　', ' ');
	$_str =~ s/^\s+|\s+$//;

	# 半角スペースで個々のキーワードに分離
	my (@keywords) = split /\s+/, $_str;

	# キーワードにNG文字があった場合のキーワードの除去
	foreach $_str (@str_ngwrd)
	{
		$_str = &replace_escape($_str);
		@keywords = grep { $_ !~ /$_str/i } @keywords;
	}

	# 検索文字が空になったらショートカット
	if (! @keywords)
	{
		&csv_to_html(@ret_arr);
		return;
	}

	# ディレクトリをオープン
	opendir DATADIR, $csv_dir or die "Serious Dainbramage: $!: $csv_dir";
	my (@allfiles) = grep /^\d{2}\.csv$/, readdir DATADIR;
	closedir DATADIR;

	# キーワードの前処理(エスケープ置換)
	foreach (0 .. $#keywords)
	{
		$keywords[$_] = &replace_escape(
			&insert_escape($keywords[$_]));
	}

	# 全CSVをオープン、全件検索
	my ($filename);
	local (@ret_arr);	# 戻り値用の配列
	my ($row);
	my ($key);
	my (%hash_match);
	my (@arr_pt);
	foreach $filename (sort @allfiles)
	{
		open(CSV,$csv_dir . '/' . $filename)
			|| die "&search: Can not open : $!: $filename\n";
		seek(CSV,0,SEEK_SET);
		%hash_match = {};
		foreach $row (<CSV>)
		{
			$row =~ s/\r\n$//;
			$row =~ s/\n$//;
			$row =~ s/\r$//;
			&jcode::convert(\$row, 'euc', 'sjis');
			@arr = split /,/, $row;
			if ($arr[$csv_col_name{rec_id}] =~ /$regex_checked_csv/)
			{
				@arr_pt = (
					&insert_escape($arr[$csv_col_name{'store'}]),
					&insert_escape($arr[$csv_col_name{'address'}]),
					&insert_escape($arr[$csv_col_name{'telephone'}])
				);

				foreach $key (@keywords)
				{
					@arr_pt = grep { /$key/i } @arr_pt;
				}

				# キーワード条件をすべて満たした。
				if (@arr_pt)
				{
					push (@{
						$hash_match{$arr[$csv_col_name{city_prefix}]}
						}, $row);
				}
			}
		}

		# 区市町村名(ひらがな)でソート
		foreach $_str (sort {$a cmp $b} keys %hash_match)
		{
			push(@ret_arr, @{ $hash_match{$_str} });
		}
	}
	&csv_to_html(@ret_arr);
}

#***************************************************************************#
#	関数名		：	csv_to_html
#	処理概要	：	CSV形式を地図詳細表示用HTMLに変換
#	パラメタ	：	CSV形式(string)
#	戻り値		：	なし
#***************************************************************************#
sub csv_to_html
{
	# 現在のページ数
	my ($curr_page) = $form{'n'};
	if ($curr_page !~ /^\d+$/)
	{
		$curr_page = 0;
	}

	# トータルのヒット件数
	my (@out_csv) = @_;
	my ($total_hits) = scalar(@out_csv);

	# 全ページ数を計算
	my ($all_pages);
	if ($total_hits % $result_per_hit)
	{
		$all_pages = int($total_hits / $result_per_hit) + 1;
	}
	else
	{
		$all_pages = $total_hits / $result_per_hit;
	}

	# 不正なページを指定してきた場合
	if ($curr_page < 0 || $curr_page >= $all_pages) {
		$curr_page = 0;
	}

	# 余分な要素をSplice
	@out_csv = splice(
		@out_csv,
		(int($result_per_hit) * int($curr_page)),
		$result_per_hit
	);

	# 地図詳細HTML
	my (@arr);
	my ($city_name);
	foreach (@out_csv)
	{
		s/\n$//;
		s/\r$//;
		s/^"(.+)"$/$1/;
		@arr = split /,/, $_;
		if ($form{'c'} ne '' && $city_name eq '')
		{
			$city_name = $arr[$csv_col_name{'city_name'}];
		}

		$html_result_list .= << "EOM";
<dl class="shopbox">
  <dt class="shopname">店舗名</dt>
  <dd class="shopname">$arr[$csv_col_name{'store'}]</dd>
  <dt class="shopaddr">住所</dt>
  <dd class="shopaddr">$arr[$csv_col_name{'address'}]</dd>
	<dt class="shoptel">電話番号</dt>
	<dd class="shoptel">$arr[$csv_col_name{'telephone'}]</dd>
</dl>
EOM
	}

	# ヘッダ
	if ($city_name)
	{
		$html_result_msg = $prefec{$form{'p'}}
			. '&nbsp;&nbsp;'
			. $city_name
			. '&nbsp;&nbsp;';
	}
	else
	{
		$html_result_msg = 'キーワード　“ ' . &htmlspecialchars($form{'q'}) . ' ”';
	}

	if ($total_hits)
	{
		#$html_result_msg .= "$total_hits件ありました。";
		$html_result_count = "$total_hits件ありました。";
	}
	else
	{
		$html_result_msg .= "見つかりませんでした。";
		$html_result_count = '';
	}

	# mapionへのリンクの表示
	if ($total_hits)
	{
		$html_mapion_link .= <<'EOM';

			<table cellpadding="0" cellspacing="0" border="0" width="100%" bgcolor="#000000">
			<tr>
			<td class="cap"><br>取扱い店舗の地図を検索する場合は地図検索サイトを開き住所を入力するなどして検索してください。<br>
			<A HREF="http://www.mapion.co.jp/" target="_blank">
			<IMG SRC="http://www.mapion.co.jp/QA/user/img/mapion_2.gif" ALT="mapion" BORDER="0"></A>
			</td>
			</tr>
			</table>
EOM
	}

	# フッタ（リンクボタン）の作成開始
	$html_result_link = <<'EOM';
<table cellpadding="0" cellspacing="0" border="0" width="590">
EOM

	$html_result_link .= <<'EOM';
<tr>
<td width="30" rowspan="4"><img src="../img/space.gif" width="30" height="1"
border="0" alt=""></td>
EOM

	$html_result_link .= <<'EOM';
<td bgcolor="#ffffff" colspan="4"><img src="../img/space.gif" width="1" height="1" border="0" alt=""></td>
</tr>
<tr>
<td colspan="4"><img src="../img/space.gif" width="1" height="10" border="0"
alt=""></td>
</tr>
EOM

	# 前のページボタン
	my ($temp_url);
	if ($curr_page)
	{
		$ENV{QUERY_STRING} =~ s/\&n\=[^&=\?]+$//;
		$temp_url = "$ENV{'SCRIPT_NAME'}?$ENV{QUERY_STRING}"
			. "&n=" . ($curr_page - 1);
	}
	elsif ($form{p} =~ /\d{2}/)
	{
		$temp_url = "$ENV{'SCRIPT_NAME'}\?p=$form{'p'}";
	}
	else
	{
		$temp_url = "./";
	}
$html_back_url = $temp_url;
$html_result_link = '';
	# 各ページへジャンプするリンク
	if ($total_hits > $result_per_hit)
	{
		# 各ページへジャンプするリンク

		# 表示する開始ページと終了ページを求める

		my ($min_page) = 0;
		my ($max_page) = $all_pages - 1;

		# 総ページ数が最大表示ページ数を上回る場合
		if ($all_pages > $display_link_num)
		{
			if (0 <= $curr_page
				&& $curr_page < int($display_link_num
					- int($display_link_num / 2)))
			{
				$max_page = $display_link_num - 1;
			}
			elsif (int($display_link_num - int($display_link_num / 2))
				<= $curr_page
				&& $curr_page < $all_pages - int($display_link_num / 2))
			{
				$min_page = $curr_page -
					int($display_link_num - int($display_link_num / 2));
				$max_page = $curr_page + int($display_link_num / 2) - 1;
			}
			elsif ($all_pages - int($display_link_num / 2) <=
				$curr_page
				&& $curr_page < $all_pages)
			{
				$min_page = $all_pages - $display_link_num;
			}
		}
		for ($i = $min_page; $i <= $max_page; $i++)
		{
		$html_result_link .= '<li>';
			if ($curr_page == $i)
			{
				$html_result_link .= $i + 1;
			}
			else
			{
				$ENV{QUERY_STRING} =~ s/\&n\=[^&=\?]+$//;
				$temp_url = "$ENV{'SCRIPT_NAME'}?$ENV{QUERY_STRING}"
					. "&n=$i";
				$html_result_link .= '<a href="' . $temp_url . '" target="_self"> '
					. ($i + 1)
					. " </a>";
			}
			if ($i < $max_page) {
				$html_result_link .= '｜</li>';
			}

		}
		$html_result_link .= "</li>";

		# 次のページリンク
		if ($curr_page + 1 < $all_pages)
		{
		$ENV{QUERY_STRING} =~ s/\&n\=[^&=\?]+$//;
			$temp_url = "$ENV{'SCRIPT_NAME'}?$ENV{QUERY_STRING}"
				. "&n=" . ($curr_page + 1);

			$html_next_url = $temp_url;
			 <<"EOM";
<li id="btnnext"><a href="$temp_url"><Img src="img/next.png" alt="next"></a></li>
EOM
		}
		else
		{
		$html_next_link = '';
		}
	}
	else
	{
	}

	&display($templ_result);
}
