#!/usr/bin/perl
# ----------------------------------------------------------------------------- #
# 各モジュールの読み込み
# ----------------------------------------------------------------------------- #
&Error('日本語モジュールが読み込めません。') unless(-f '../bin/jcode.pl');
require '../bin/jcode.pl';   # 日本語モジュール

&Error('記事作成設定ファイルが読み込めません。') unless(-f '../bin/ApproachConfig.pl');
require '../bin/ApproachConfig.pl';

my (@NewsList);

my (%FORM);
my (@CATE);
my (%HTML);
my (@VIEW_LIST);

my (@SRCH_DIR);			# 検索対象ディレクトリ
my (@DIR_LIST);			# 検索結果ディレクトリ
my (@SRCH_WORDS);		# 検索ワード

my ($P_PREV, $P_NEXT);	# 前ページ、次ページフラグ

if (!$BaseUrl) {
	if($ENV{SCRIPT_URI}) {
		$BaseUrl = $ENV{SCRIPT_URI};
	} else {
		$BaseUrl = "$ENV{HTTP_HOST}$ENV{SCRIPT_NAME}";
	}
	if ($BaseUrl =~ /^(.*)\/(.*\.cgi)$/io ) {
		($BaseUrl, $VIEW_SCRIPT) = ($1, $2);
	}
}

$BaseUrl = "http://$BaseUrl" if ($BaseUrl !~ /^http:\/\//io);

$ViewDir =~ s/\/$//o;

# カテゴリ情報取得
&ReadCategoryFile($CateFile, \@CATE);

# フォームデータ取得
&ReadFormData;

# ----------------------------------------------------------------------------- #
# メイン処理
# ----------------------------------------------------------------------------- #
&GetViewList($ViewDir, \@VIEW_LIST);

$FORM{page} = 1 if (($FORM{status} eq 'srch' && !$FORM{word}) || ($FORM{status} ne 'srch' && $FORM{word}) || ($FORM{category} ne $FORM{cate}));
$FORM{status} = ($FORM{word}) ? 'srch' : 'list';


if($FORM{'word'}) {
	my (@news);
	&MakeSearchDir($FORM{'cate'}, \@SRCH_DIR);
	&NewsSearch($FORM{'cate'}, \@SRCH_DIR, \@news);

	$FORM{'page'}-- if ($FORM{'mode'} eq 'prev' && $FORM{'page'} > 1);
	$FORM{'page'}++ if ($FORM{'mode'} eq 'next');

	my ($PAGE) = (!$FORM{'page'}) ? 1 : $FORM{'page'};
	my $first = ($PAGE - 1) * $MAX_ROWS;
	$first = 0 if $first < 0;
	my $end = ($PAGE * $MAX_ROWS) - 1;
	$end = ($end <= $#news) ? $end : $#news;

	# 表示モードによりソート処理
# 20080606 Update
	my (@tmp) = map {(split /\t/)[0] =~ m/([\\\/].+[\\\/].+[\\\/].+$)/o; $1 } @news;
	@news = @news[sort {$tmp[$b] cmp $tmp[$a]} 0 .. $#tmp];

#	my (@tmp) = map {(split /\t/)[0] =~ m/(\d+[\\\/]\d+[\\\/])/o; $1 } @news;
	my (@tmp) = map {(split /\t/)[2] =~ m/(\d+[\\\/]\d+[\\\/]\d+)/o; $1 } @news;
	@news = @news[sort {$tmp[$b] cmp $tmp[$a]} 0 .. $#tmp];
#

	undef @NewsList;
	for my $idx ($first .. $end) {
		push @NewsList, $news[$idx];
	}

	$P_PREV = ($first > 0) ? 1 : 0;
	$P_NEXT = ($end < $#news) ? 1 : 0;

	&ReadViewTemplate($VIEW_LIST[$FORM{'style'}]{FILE}, \%HTML);
	&MakeViewBody($FORM{'cate'}, $FORM{'style'}, 1, 1)
} elsif ($FORM{'mode'} eq 'make' or exists $FORM{'make'}) {

	# バージョンアップ用（仮）
	foreach my $cate ( 1 .. $#CATE) {
		undef @NewsList;
		# ニュースリストの作成
		&MakeNewsList("$CATE[$cate]{DIR}", $cate);

		my (@tmp1);

		foreach (@NewsList) {
			m/(\d+)\/(\d+)\//g;
			push(@tmp1, "$1$2");
		}

		@NewsList = @NewsList[sort {$tmp1[$a] cmp $tmp1[$b]} 0 .. $#tmp1];

		if (open FH, ">$CATE[$cate]{DIR}/cate${cate}_list.pl") {
			print FH "$_\n" foreach(@NewsList);
			close FH;
		}
	}
	&Error('終了');
} else {
	$FORM{'page'}-- if ($FORM{'mode'} eq 'prev' && $FORM{'page'} > 1);
	$FORM{'page'}++ if ($FORM{'mode'} eq 'next');

	if (!$FORM{'cate'}) {
		for(0 .. $#CATE) {
			if( defined($CATE[$_]{NAME}) ) {
				$FORM{'cate'} = $_;
				last;
			}
		}
	}

	&ReadViewTemplate($VIEW_LIST[$FORM{'style'}]{FILE}, \%HTML);
	&MakeViewBody($FORM{'cate'}, $FORM{'style'}, 1);
}

exit;

# ----------------------------------------------------------------------------- #
# フォームデータ取得処理
# ----------------------------------------------------------------------------- #
sub ReadFormData
{

	my ($method);
	my ($name, $value);
	my ($buffer);
	my (@pairs);

	$method = $ENV{'REQUEST_METHOD'};

	# フォームからのデータを取得
	if ( $method eq 'POST') {
		# 'POST'
		read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
	} else {
		# 'GET'
		$buffer = $ENV{'QUERY_STRING'};
	}

	@pairs = split(/&/, $buffer);

	foreach (@pairs) {
		($name, $value) = split(/=/, $_);
		$name =~ tr/+/ /;
		$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
		$value =~ tr/+/ /;
		$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

		$FORM{$name} = $value;
	}

	if ($FORM{'cate'} !~ /\d+?/io) {
		foreach(0 .. scalar @CATE) {
			next if(!defined $CATE[$_]{NAME});
			if ($FORM{'cate'} eq $CATE[$_]{NAME} && $FORM{'cate'} =~ m/^$CATE[$_]{NAME}$/io) {
				$FORM{'cate'} = $_;
				last;
			}
		}
	}

	$FORM{status} = ($FORM{word}) ? 'srch' : 'list' if(!$FORM{status});
}

# ------------------------------------------------------------------------------------------ #
# カテゴリ管理ファイル読込み
# ------------------------------------------------------------------------------------------ #
sub ReadCategoryFile
{

	my ($File, $Cate) = @_;

	$Cate->[0]{NAME} = '全カテゴリ';
	$Cate->[0]{DIR} = '';

	open FH, "$File" || return;
	while(<FH>) {
		chomp;
		next if(!$_);

		my ($no, $name, $dir) = split(/\t/, $_);

		$dir =~ s/\/$//o;

		$Cate->[$no]{NAME} = $name;
		$Cate->[$no]{DIR} = $dir;
	}
	close FH;

}

# ------------------------------------------------------------------------------------------ #
# 表示用ボディ作成。
# ------------------------------------------------------------------------------------------ #
sub MakeViewBody
{

	my ($Cate, $Style, $view, $Maked) = @_;

	# ニュースリストの作成
	($P_PREV, $P_NEXT) = &MakeNewsList1($Cate, $MAX_ROWS, $FORM{'page'}) if(!$Maked);


	# 表示モードによりソート処理

# 20080606 Update
	my (@tmp) = map {(split /\t/)[0] =~ m/([\\\/].+[\\\/].+[\\\/].+$)/o; $1 } @NewsList;
	@NewsList = @NewsList[sort {$tmp[$b] cmp $tmp[$a]} 0 .. $#tmp];

#	my (@tmp) = map {(split /\t/)[0] =~ m/(\d+[\\\/]\d+[\\\/])/o; $1 } @NewsList;
	my (@tmp) = map {(split /\t/)[2] =~ m/(\d+[\\\/]\d+[\\\/]\d+)/o; $1 } @NewsList;
	@NewsList = @NewsList[sort {$tmp[$b] cmp $tmp[$a]} 0 .. $#tmp];
#

	&DispTemplateBody($Cate, \%HTML);

}


# ----------------------------------------------------------------------------- #
# 一覧表示（対象ファイル抽出処理）
# ----------------------------------------------------------------------------- #
sub MakeNewsList
{

	my($Dir, $Cate) = @_;
	my(@DirList);

	opendir(DIR, $Dir);
	@DirList = readdir(DIR);
	closedir(DIR);

	$Dir =~ s/\/$//;

	foreach (@DirList) {
		next if ( $_ =~ /^\.\.?/);

		my ($file) = "$Dir/$_";
		if (-d $file) {
			&MakeNewsList($file, $Cate);
		} else {
			if ( $_ =~ /newsconf\.pl/io) {
				push @NewsList, $file if(&ReadNewsInfo($file, $Cate));
			}
		}
	}
}


# ----------------------------------------------------------------------------- #
# 管理ファイル（ヘッダー取得）
# ----------------------------------------------------------------------------- #
sub ReadNewsInfo()
{

	my ($File, $Cate) = @_;
	my ($checked);

	return if ($File =~ /\/temp\//io);

	open ( FH, "$File") or print "ERR";
	foreach (<FH>) {
		chomp;
		next unless($_);

		my ($name, $value, $img) = split( /\t/, $_);

		if(!$img && $name eq 'category' && $value == $Cate) {
			$checked = 1;
			last;
		}
	}
	close (FH);

	return $checked;

}

# ------------------------------------------------------------------------------------------ #
# エラー処理
# ------------------------------------------------------------------------------------------ #
sub Error
{

  my (@errs) = @_;  # エラー内容
  my ($msg);

  $msg .= "<B>$_</B><BR>\n" foreach (@errs);

print <<"EOM";	
Content-type: text/html

<HTML>
<HEAD>
<!---
  <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
--->
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=x-sjis">
  <TITLE>エラー</TITLE>
</HEAD>

<BODY>
<DIV ALIGN="CENTER">
  <P><H3><B>Error !!</B></H3></P>
  <HR WIDTH="100%" noshade size="5">
  <P>$msg</P>
  <HR WIDTH="100%" noshade size="5">
</DIV>
</BODY>
</HTML>
EOM

  exit;
}


# ----------------------------------------------------------------------------- #
# 検索対象ディレクトリリスト作成処理
# ----------------------------------------------------------------------------- #
sub MakeSearchDir
{
	my ($Cate, $Dirs) = @_;

	# 選択カテゴリより、検索対象ディレクトリリストの作成
	if($Cate) {
		push @{$Dirs}, "$CATE[$Cate]{DIR}\t$Cate";
	} else {
		my (%temp);
		for my $idx (0 .. $#CATE) {
#			$temp{$CATE[$idx]{DIR}} = 1 if ($CATE[$idx]{DIR});
			push @{$Dirs}, "$CATE[$idx]{DIR}\t$idx" if ($CATE[$idx]{DIR});
		}

#		push @{$Dirs}, $_ foreach(keys(%temp));
	}

}

# ----------------------------------------------------------------------------- #
# サイト検索（対象ファイル抽出処理）
# ----------------------------------------------------------------------------- #
sub NewsSearch
{

	my($Category, $SrchDir, $DirList) = @_;
	my(@Lists, $file, $ext);

	foreach my $tmp (@{$SrchDir}) {
		my ($Dir, $cate) = split(/\t/, $tmp);
		my ($Cate) = ($Category) ? $Category : $cate;

		opendir(DIR, $Dir);
		@Lists = readdir(DIR);
		closedir(DIR);

		foreach (@Lists) {
			next if(/\.\.?$/);
			next if(/temp/io);

			$file = "$Dir/$_";
			if (-d $file) {
				my (@dir) = $file;
				&NewsSearch($Cate, \@dir, $DirList);
			} else {
				&FindSearchFiles($DirList, $file, $Cate, $FORM{'word'}, $FORM{'cond'}) if (/newsconf\.pl/io);
			}
		}
	}

}

# ----------------------------------------------------------------------------- #
# サイト検索単語マッチ処理 [対象ファイル, カテゴリ, 検索ワード, 検索条件]
# ----------------------------------------------------------------------------- #
sub FindSearchFiles
{

	my ($Lists, $File, $Category, $Freeword, $Cond) = @_;

	# 各種変数を初期化する
	my (%Conf);
	my ($Multibyte);

	open (FH, "$File") || return;
	my (@lines) = <FH>;
	close FH;

	my (@inspcts);
# 20080606 Add
	my ($art_date);
#
	foreach (@lines) {
		chomp;
		next unless($_);

		my ($name, $value, $image) = split( /\t/, $_);
		next if ($image || ($name =~ /psw/io));

		# カテゴリが違う場合には、対象外
		return if ($Category != 0 && $name =~ /category/io && $value != $Category);
		
# 20080606 Add
		# 記事の日付を取得する
		if ($name =~ /date/io) { $art_date = $value };
		# 記事の日付をYYYY/MM/DD形式に変換する
		my ($t_year, $t_month, $t_day) = split( /\//, $art_date);
		$art_date = sprintf("%04d", $t_year) . '/' . sprintf("%02d", $t_month) . '/' . sprintf("%02d", $t_day);
#
	}

	if ($Freeword) {
		if ($Freeword =~ /[\x80-\xff]/) {
			$Multibyte = 1;
			&jcode::convert(\$Freeword, 'euc');
			$Freeword =~ s/([\x80-\xff][\x80-\xff]|[\x00-\x7f])/($1 eq "\xa1\xa1") ? " " : $1/eg;
			&jcode::convert(\$Freeword, 'sjis');
		} else {
			$Freeword =~ s/([\+\*\.\?\^\$\[\-\]\|\(\)\\])/\\$1/g;
		}

		my (@Keywords) = split(/ +/, $Freeword);
		my ($Count) = 0;
		my (%Finish);

		$Finish{$_} = 0 foreach(@Keywords);

		foreach my $line (@lines) {
			my $last;
			my ($name, $line, $temp) = split(/\t/, $line);
			next if ($temp || $name =~ /psw/i);

			foreach my $cond (@Keywords) {
				next if($Finish{$cond});		# すでに、マッチ済みなら次へ

				if ($Multibyte) {
					next if(index($line, $cond) == -1);
				} else {
					next if($line !~ /$cond/i);
				}

				$Finish{$cond} = 1;

				next if(($Cond =~ /and/io) && (++$Count < $#Keywords + 1 ));

# 20080606 Update
#				push @{$Lists}, "$File\t$Category";
				push @{$Lists}, "$File\t$Category\t$art_date";
#
				$last = 1;
				last;
			}
			last if($last);
		}
	} else {
# 20080606 Update
#		push @{$Lists}, "$File\t$Category";
		push @{$Lists}, "$File\t$Category\t$art_date";
#
	}
}

# ----------------------------------------------------------------------------- #
#  画像ファイルのサイズ取得を行なう。（サイズ指定の場合、同比率のサイズを返す）
# ----------------------------------------------------------------------------- #
sub GetImageSize() {

  my ($file, $maxx, $maxy ) = @_;
  my ($header, $type, $ratio);
  my ($x, $y);

  # ファイルの存在チェック
  return unless( -f "$file" );

  # 対象ファイルのオープン
  open IN, "$file";

  seek IN, 0 ,0;
  # Windowsでは、バイナリモードで
  binmode(IN);

  # ヘッダー部を読みファイル種別を特定する。
  read IN, $header, 8;
  seek IN, 0, 0;

  # ファイル種別により、処理の振り分け
  if($header =~ /^GIF8[79]a/) {
    $type = "gif";
    ($x, $y) = &GetGifSize(\*IN);
  } elsif($header =~ /^\xFF\xD8/) {
    $type = "jpg";
    ($x, $y) = &GetJpgSize(\*IN);
  } elsif($header =~ /^\x89PNG\x0D\x0A\x1A\x0A/) {
    $type = "png";
    ($x, $y) = &GetPngSize(\*IN);
  }

  seek IN, 0, 0;
  close IN;

  if ( $maxx || $maxy ) {
    if ( $x && $y ) {
      if ( $x > $maxx ) {
        $ratio = $maxx / $x;
        if (( $y * $ratio ) <= $maxy ) {
          $x = $maxx;
          $y = $y * $ratio;
        }
      }
    
      if ( $y > $maxy ) {
        $ratio = $maxy / $y;
        if (( $x * $ratio ) <= $maxx ) {
          $x = $x * $ratio;
          $y = $maxy;
        }
      }

      $x = int $x;
      $y = int $y;
    }
  }

  return($x, $y, $type);

}

# ----------------------------------------------------------------------------- #
# GIF画像用サイズ取得処理
# ----------------------------------------------------------------------------- #
sub GetGifSize() {

  my ($fh) = shift;
  my ($x, $y) = (undef, undef);
  my $buf;

  # 先頭から 10 バイトを読み込む。
  seek($fh, 0, 0);
  read($fh, $buf, 10);

  # リトルエンディアンの short 
  ($x, $y) = unpack("x6 vv", $buf);
  return($x, $y);
}

# ----------------------------------------------------------------------------- #
# PNG画像用サイズ取得処理
# ----------------------------------------------------------------------------- #
sub GetPngSize() {

  my ($fh) = shift;
  my ($x, $y) = (undef,undef);
  my $buf;

  # 先頭から 24 バイト読み込む。
  seek($fh, 0, 0);
  read($fh, $buf, 24);

  ($x, $y) = unpack("x16 NN", $buf);
  return($x, $y);
}

# ----------------------------------------------------------------------------- #
# JPG画像用サイズ取得処理
# ----------------------------------------------------------------------------- #
sub GetJpgSize {

  my ($fh) = shift;
  my ($marker, $buf, $code, $len);
  my ($x, $y) = (undef, undef);

  # 先頭 2 バイトを読み飛ばす
  read($fh, $buf, 2);

  for(;;){
    my $tmp_marker;

    $len = 4;
    read($fh, $tmp_marker, $len);

    # マーカー,マーカーのサイズ情報を取得
    ($marker, $code, $len) = unpack("a a n", $tmp_marker);
    # マーカーの読み飛ばしに失敗? あきらめてループから脱出
    if($marker ne "\xFF") { 
      last;
    } elsif( ord($code) >= 0xC0 && ord($code) <= 0xC3) {
      # サイズ情報が含まれてるマーカーを発見
      my $buf;
      $len = 5;
      read($fh, $buf, $len);
      ($y, $x) = unpack("xnn", $buf);
      last;
    } else { 
      # マーカー情報を読み飛ばす、マーカーのサイズ情報自体が含まれてるので 2 引く
      my $tmp;
      read($fh, $tmp, $len - 2);
    }
  }

  return($x, $y);
}

# ----------------------------------------------------------------------------- #
# 【表示用テンプレート読込み処理】（相対パス変換）
#
#		引数：	$File	テンプレート名
#				$Html	テンプレート格納用（ハッシュリファレンス）
#
#		$HTML->{HEAD}		ページヘッダ１
#		$HTML->{B_TOP}		ページフッタ２
#		$HTML->{B_HEAD}		COLSヘッダ
#		$HTML->{B_DETAIL}	記事明細
#		$HTML->{B_FOOT}		COLSフッタ
#		$HTML->{B_BOTTOM}	ページフッタ２
#		$HTML->{FOOT}		ページフッタ１
#
# ----------------------------------------------------------------------------- #
sub ReadViewTemplate
{

	my ($File, $Html) = @_;

	my ($cols, $stage);

	my (@BodyPath) = split('/', $File);
	pop @BodyPath;
	my ($BodyPath) = join('/', @BodyPath);
	my (%ImageList);

	open FH, "$File" or &Error('テンプレートファイルの読込みに失敗しました。', $@, "ファイル名：［$File］");
	my (@Lines) = (<FH>);
	close FH;

	my (@BODY_LIST) = &ExtractImageFile(@Lines);
	&MakeImageList(\%ImageList, $BodyPath, @BODY_LIST);

	foreach my $line (@Lines) {

		foreach my $image (keys(%ImageList)) {
			$line =~ s/$image/$ImageList{$image}/eg;
		}

		if($stage == 0) {
			if($line =~ /<!-+(\s*)?HEAD(\s*)?START(\s*)?-+?>/io) {
				$stage = 1;
			} elsif($line =~ /<!-+(\s*)?BODY(\s*)?START(\s*)?-+?>/io) {
				$stage = 3;
			} else {
				push @{$Html->{HEAD}}, $line;
			}
		} elsif($stage == 1) {
			if($line =~ /<!-+(\s*)?HEAD(\s*)?END(\s*)?-+?>/io) {
				$stage = 2;
			} elsif($line =~ /<!-+(\s*)?BODY(\s*)?START(\s*)?-+?>/io) {
				$stage = 3;
			} else {
				push @{$Html->{B_TOP}}, $line;
			}
		} elsif($stage == 2) {
			if($line =~ /<!-+(\s*)?BODY(\s*)?START(\s*)?-+?>/io) {
				$stage = 3;
			}
		} elsif($stage == 3) {
			if($line =~ /<!-+(\s*)?BODY(\s*)?COLS\s+?(\d*)?(\s*)?-+>/io) {
				$Html->{COLS} = $3;
				$stage = 4;
			} elsif($line =~ /<!-+(\s*)?BODY(\s*)?END(\s*)?-+?>/io) {
				$stage = 6;
			} else {
				push @{$Html->{B_HEAD}}, $line;
			}
		} elsif($stage == 4) {
			if($line =~ /<!-+(\s*)?BODY(\s*)?COLS\s+?END(\s*)?-+>/io) {
				$stage = 5;
			} elsif($line =~ /<!-+(\s*)?BODY(\s*)?END(\s*)?-+?>/io) {
				$stage = 6;
			} elsif($line =~ /<!-+(\s*)?FOOT(\s*)?START(\s*)?-+?>/io) {
				$stage = 7;
			} else {
				push @{$Html->{B_DETAIL}}, $line;
			}
		} elsif($stage == 5) {
			if($line =~ /<!-+(\s*)?BODY(\s*)?END(\s*)?-+?>/io) {
				$stage = 6;
			} elsif($line =~ /<!-+(\s*)?FOOT(\s*)?START(\s*)?-+?>/io) {
				$stage = 7;
			} else {
				push @{$Html->{B_FOOT}}, $line;
			}
		} elsif($stage == 6) {
			if($line =~ /<!-+(\s*)?FOOT(\s*)?START(\s*)?-+?>/io) {
				$stage = 7;
			} else {
				push @{$Html->{FOOT}}, $line;
			}
		} elsif($stage == 7) {
			if($line =~ /<!-+(\s*)?FOOT(\s*)?END(\s*)?-+?>/io) {
				$stage = 8;
			} else {
				push @{$Html->{B_BOTTOM}}, $line;
			}
		} else {
			push @{$Html->{FOOT}}, $line;
		}
	}

	if(!$Html->{COLS}) {
		@{$Html->{BODY}} = @{$Html->{B_HEAD}};
		undef $Html->{B_HEAD};
	}
}

# ----------------------------------------------------------------------------- #
# 【テンプレート置換処理】
#
#      引数：$Html	テンプレート情報（ハッシュリファレンス）
# ----------------------------------------------------------------------------- #
sub DispTemplateBody
{

	my ($Cate, $Html) = @_;
	my ($idx) = 0;
	my ($first) = 1;

	my ($cate_combo) = &MakeCateCombo($FORM{'cate'});
	my ($view_combo) = &MakeViewCombo($FORM{'style'});
	my ($RepCate);
	my (%SITE_TEMP);

	my ($cond);
	if ($FORM{'cond'} =~ /or/io) {
		$cond .= qq{<input type="radio" name="cond" value="AND" />AND&nbsp;<input type="RADIO" name="cond" value="OR" checked="checked" />OR};
	} else {
		$cond .= qq{<input type="radio" name="cond" value="AND" checked="checked" />AND&nbsp;<input type="RADIO" name="cond" value="OR" />OR};
	}

	my ($word) = qq{<input type="text" name="word" size="10" value="$FORM{word}" />\n};

	my ($srch_button) = qq{<input type="button" value="検　索" onClick="cmdexec('srch')" style="cursor:hand" />\n};
	my ($view_button) = qq{<input type="button" value="\表\　\示" onClick="cmdexec('view')" style="cursor:hand" />\n};


	$P_NEXT = ($P_NEXT) ? '' : 'disabled="disabled"';
	$P_PREV = ($P_PREV) ? '' : 'disabled="disabled"';

	my ($prev_button) = qq{<input type="button" name="prev" value="&lt;&lt;&nbsp;前ページへ" onClick="cmdexec('prev')" $P_PREV />\n};
	my ($next_button) = qq{<input type="button" name="next" value="&gt;&gt;&nbsp;次ページへ" onClick="cmdexec('next')" $P_NEXT />\n};

	print "HTTP/1.0 200 OK\r\n" if $ENV{PERLXS} eq "PerlIS";
	print "Content-type: text/html\n";
#	print "Cache-Control: no-cache, must-revalidate\n";		# HTTP/1.1
#	print "Pragma: no-cache\n";								# HTTP/1.0
	print "\n";

	# サイトテンプレートが設定されている、かつ、存在するなら
	if ($SITE_TEMPLATE && -f $SITE_TEMPLATE) {
		&ReadViewTemplate($SITE_TEMPLATE, \%SITE_TEMP);

		@{$Html->{HEAD}} = @{$SITE_TEMP{HEAD}};
		@{$Html->{FOOT}} = @{$SITE_TEMP{FOOT}};

	}

	push @{$Html->{HEAD}}, @{$Html->{B_TOP}};
	unshift @{$Html->{FOOT}}, @{$Html->{B_BOTTOM}};

	my (%COMMAND);
	&SetReplaceCommands(\%COMMAND);

	foreach my $line (@{$Html->{HEAD}}) {

		$RepCate = 1 if ($line =~ s/\@category/$CATE[$Cate]{NAME}/ie);

		$line = &ReplaceNewsCommand($line, \%COMMAND);

		$line =~ s/\@CATE/$cate_combo/ie;		# カテゴリコンボ
		$line =~ s/\@VIEW/$view_combo/ie;		# 表示形式コンボ

		$line =~ s/\@COND/$cond/ie;				# 検索条件
		$line =~ s/\@WORD/$word/ie;				# 検索ワード

		$line =~ s/\$COND\$/$FORM{cond}/ie;
		$line =~ s/\$WORD\$/$FORM{word}/ie;		# 検索ワード（入力内容）
		$line =~ s/\$CATE\$/$CATE[$FORM{'cate'}]{NAME}/ie;
		$line =~ s/\$VIEW\$/$VIEW_LIST[$FORM{'style'}]{NAME}/ie;
		$line =~ s/\$STYLE\$/$VIEW_LIST[$FORM{'style'}]{NAME}/ie;

		$line =~ s/\#CATE\#/$FORM{'cate'}/ie;
		$line =~ s/\#VIEW\#/$FORM{'style'}/ie;
		$line =~ s/\#STYLE\#/$FORM{'style'}/ie;

		if ($line =~ /<\/HEAD>/io) {
			print qq{<script language="javascript">\n};
			print qq{<!--\n};
			print qq{function cmdexec(name) \{\n};
			print qq{	document.form.mode.value = name;\n};
			print qq{	document.form.submit();\n};
			print qq{\}\n};
			print qq{//-->\n};
			print qq{</script>\n};
			print $line;
		} elsif ($line =~ /<BODY/io) {
			print $line;
			print qq{<form name="form" action="$VIEW_SCRIPT" method="post">\n};
			print qq{<input type="hidden" name="mode" value="" />\n};
			print qq{<input type="hidden" name="status" value="$FORM{status}" />\n};
		} else {
			print $line;
		}
	}

	if ( defined $Html->{COLS} ) {
		$hl_template = join("", @{$Html->{B_DETAIL}});
	} else {
		$hl_template = join("", @{$Html->{BODY}});
	}

	&MakeHlItems($hl_template, \%hl_items);

	# 明細作成
	foreach my $tmp (@NewsList) {
		my ($file, $Cate) = split(/\t/, $tmp);

		my %CONF;
		# 記事管理ファイル読込
		&ReadConfigFile($file, \%CONF) or next;

		my ($hl_temp) = $hl_template;

		# テンプレートから、置換項目の取得
		undef $hl_items{$_} foreach(keys(%hl_items));

		if( defined $Html->{COLS} ) {
			if($idx <= 1) {
				if($first != 0) {
					$first = 0;
				} else {
					print @{$Html->{B_FOOT}};
				}
				print @{$Html->{B_HEAD}};
				$idx = $Html->{COLS};
			} else {
				$idx--;
			}
		} else {
			$idx = 0;
		}

		foreach my $item (keys(%CONF)) {
			next if ($item !~ m/DEF_(\w+)/io);

			my ($fld) = $1;
			# 初期値項目
			if (exists $hl_items{"\@$fld"}) {
				# 新着テンプレートに定義されてあれば
				if (exists $CONF{$CONF{"DEF_$fld"}}{type}) {
					# 画像項目
#					my ($url) = &MakePath(1, "$CATE[$Cate]{DIR}/$CONF{dir}/");
					my ($url) = "$CATE[$Cate]{DIR}/$CONF{dir}/";
					my ($image, $simg);
					if( exists $CONF{$CONF{"DEF_$fld"}}{small} ) {
						$image = $CONF{$CONF{"DEF_$fld"}}{small};
					} elsif( exists $CONF{$CONF{"DEF_$fld"}}{value} ) {
						$image = $CONF{$CONF{"DEF_$fld"}}{value};
					}
					$simg = $image;
					if(my ($param) = $hl_temp =~ /<(\@$fld[^>\n]*)?>/io) {
						my ($x) = $param =~ /width\s*?=\s*?["']?(\d+)["']?/io;
						my ($y) = $param =~ /height\s*?=\s*?["']?(\d+)["']?/io;
							if ($image) {
							my ($border) = $param =~ /(border\s*?=\s*?["']?\d+["']?)/io;
							my ($vspace) = $param =~ /(vspace\s*?=\s*?["']?\d+["']?)/io;
							my ($hspace) = $param =~ /(hspace\s*?=\s*?["']?\d+["']?)/io;
							my ($align) = $param =~ /(align\s*?=\s*?["']?\S+["']?)/io;
							my ($alt) = $param =~ /(alt\s*?=\s*?["']?\S+["']?)/io;		# '
							($x, $y) = &GetImageSize("$CATE[$Cate]{DIR}/$CONF{dir}/$simg", $x, $y);
							
# 20080626 Add
							$attach_path = "$CATE[$Cate]{DIR}/$CONF{dir}/$CONF{ART}{value}";
							$hl_temp =~ s/\@ATTACH_PATH/$attach_path/ig;
#
							
							$dst = qq{IMG SRC="$url/$image" WIDTH="$x" HEIGHT="$y"};
							$dst .= " $border" if($border);
							$dst .= " $vspace" if($vspace);
							$dst .= " $hspace" if($hspace);
							$dst .= " $align" if($align);
							if ($alt =~ /\@(\w+)/) {
								my ($fld) = $1;
								$alt =~ s/\@$fld/$CONF{$CONF{"DEF_$fld"}}/ei;
							}

							$dst .= " $alt" if($alt);
							$dst = "<$dst>";
						} else {
							# イメージの代わりに空のテーブルを用意
			#				$dst = qq{<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0"><TD WIDTH="$x">&nbsp;</TD></TR></TABLE>};
							$dst = '';
						}
						$fld = "\@$fld";
						$hl_items{$fld} = $dst;
						$hl_temp =~ s/<$fld[^>]+?>/$fld/ie;
					}
				} elsif($fld =~ /DATE/io) {
					# 日付項目
					my ($date_fmt) = ($HL_DATE_FORMAT) ? $HL_DATE_FORMAT : 'yyyy.mm.dd';
					($hl_items{"\@$fld"}) = &MakeDateFormat($date_fmt, substr($CONF{dir}, 0, 4), substr($CONF{dir}, 5, 2), substr($CONF{dir}, 7, 2));
				} elsif( $fld =~ /icon/i && $CONF{$CONF{"DEF_$fld"}} =~ /^\d+$/) {
					
					# アイコン項目
#					my ($icon)  = &MakePath(1, "$IconDir/");
					my ($icon)  = "$IconDir/";
					$icon .= '/' if ($icon !~ /\/$/o);
					$icon .= $ICONS[$CONF{$CONF{"DEF_$fld"}}]{LINK};

					if(my ($param) = $hl_temp =~ /<(\@$fld[^>\n]*)?>/io) {
						my ($x) = $param =~ /width\s*?=\s*?["']?(\d+)["']?/io;
						my ($y) = $param =~ /height\s*?=\s*?["']?(\d+)["']?/io;
	
						if ($icon) {
							my ($border) = $param =~ /(border\s*?=\s*?["']?\d+["']?)/io;
							my ($vspace) = $param =~ /(vspace\s*?=\s*?["']?\d+["']?)/io;
							my ($hspace) = $param =~ /(hspace\s*?=\s*?["']?\d+["']?)/io;
							my ($align) = $param =~ /(align\s*?=\s*?["']?\S+["']?)/io;
							my ($alt) = $param =~ /(alt\s*?=\s*?["']?\S+["']?)/io;		# '
							($x, $y) = &GetImageSize("$IconDir/" .$ICONS[$CONF{$CONF{"DEF_$fld"}}]{LINK}, $x, $y);
							$dst = qq{IMG SRC="$icon" WIDTH="$x" HEIGHT="$y"};
							$dst .= " $border" if($border);
							$dst .= " $vspace" if($vspace);
							$dst .= " $hspace" if($hspace);
							$dst .= " $align" if($align);
							$dst .= " $alt" if($alt);
							$dst = "<$dst>";
						} else {
							# イメージの代わりに空のテーブルを用意
			#				$dst = qq{<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0"><TD WIDTH="$x">&nbsp;</TD></TR></TABLE>};
							$dst = '';
						}
						$fld = "\@$fld";
						$hl_items{$fld} = $dst;
						$hl_temp =~ s/<$fld[^>]+?>/$fld/ie;
					}
				} elsif( $fld =~ /title/i) {
#					my ($url) = &MakePath(1, "$CATE[$Cate]{DIR}/$CONF{dir}");
					my ($url) = "$CATE[$Cate]{DIR}/$CONF{dir}";
					$hl_items{"\@$fld"} = ($CONF{$CONF{"DEF_$fld"}}) ? qq{$CONF{$CONF{"DEF_$fld"}}} : qq{無題};
				} else {
					# テキスト項目
					my ($str) = &zsubstr($CONF{$CONF{"DEF_$fld"}}, 0, $HL_TEXT);
					$str .= '...' if($str ne $CONF{$CONF{"DEF_$fld"}});
					$hl_items{"\@$fld"} = $str;
				}
			}
		}

		$url = "$CATE[$Cate]{DIR}/$CONF{dir}";

		$hl_temp =~ s/\@URL/$url/ig;
		$hl_temp =~ s/\@PAGE/$url\/index\.html/ig;
		
		foreach my $item (keys(%hl_items)) {
			my $fld = $item;
			$fld =~ s/\@//;
			$fld = uc($fld);
			if (!exists $CONF{"DEF_$fld"}) {
				$hl_temp =~ s/<($item[^>\n]*)?>//eg;
				$hl_temp =~ s/$item//eg;
			} else {
				$hl_temp =~ s/$item/$hl_items{$item}/eg;
			}
		}

		print $hl_temp;
	}

	# 複数列表示の余り対策
	if( defined $Html->{COLS} ) {
#		for(1 .. $idx){
#			print qq{<TD>&nbsp;</TD>\n};
#		}
		@bodys = @{$Html->{B_DETAIL}};
		for(2 .. $idx) {
			foreach(@bodys) {
				chomp;
				if ($_ =~ m/width\s*?=[\"\'\s]?(\d+)[\'\"\s>]?/io) {
					print qq{<TD WIDTH="$1">&nbsp;</TD>\n};
					last;
				}
			}
		}
	}

	print @{$Html->{B_FOOT}} if( defined $Html->{COLS} && !$first);

	$FORM{'page'} = 1 if (!$FORM{'page'});
	print qq{<input type="hidden" name="page" value="$FORM{'page'}" />\n};
	print qq{<input type="hidden" name="category" value="$FORM{'cate'}" />\n} if($RepCate);

	foreach my $line (@{$Html->{FOOT}}) {
		$line = &ReplaceNewsCommand($line, \%COMMAND);

		print qq{</form>\n} if( $line =~ /<\/BODY/io);
		print $line;
	}

}


# ----------------------------------------------------------------------------- #
# 新着テンプレートの項目一覧作成
# ----------------------------------------------------------------------------- #
sub MakeHlItems
{
	my ($hl_temp, $hl_items) = @_;

	my (@hl_lines) = split(/\n/, $hl_temp);

	# 新着テンプレートチェック
	foreach my $line (@hl_lines) {
		if (my (@Match) = $line =~ m/(\@\w+)/ig) {
			foreach(@Match) {
				$hl_items->{$_} = $_;
			}
		}
	}

	return;
}

# ----------------------------------------------------------------------------- #
# 全角で？文字取得
# ----------------------------------------------------------------------------- #
sub zsubstr {

	my ($str, $pos, $len) = @_;

	$str =~ s/(.)/$1\0/g;
	$str =~ s/([\x81-\x9f\xe0-\xfc])\0(.)\0/$1$2/g;
	$str = ($len eq '') ? substr($str, $pos * 2) : substr($str, $pos * 2, $len * 2);
	$str =~ tr/\0//d;

	return $str;
}
# ----------------------------------------------------------------------------- #
# 表示用日付のフォーマット指示に従い作成を行う。
# ----------------------------------------------------------------------------- #
sub MakeDateFormat {

	my ($fdate, $def_year, $def_mon, $def_day) = @_;

	my ($y, $m, $d, $h, $n, $s, $j, $w);
	my ($f_y, $f_m, $f_d, $f_h, $f_n, $f_s, $f_j, $f_w);
	my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);


	$fdate = 'yyyy/mm/dd' if(!$fdate);

	if ($def_year && $def_mon && $def_day) {
		($year, $mon, $mday ) = ($def_year, $def_mon, $def_day);
	} else {
		($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
		$year += 1900;
		$mon++;
	}

	my @weekday_j = ( '日', '月', '火', '水', '木', '金', '土' );
	my @weekday = ( 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday','Friday','Saturday');

	$y = $1 if($fdate =~ m/(y+)/o);
	$m = $1 if($fdate  =~ m/(m+)/o);
	$d = $1 if($fdate  =~ m/(d+)/o);

	$w = $1 if($fdate  =~ m/(w+)/o);
	$j = $1 if($fdate  =~ m/(j+)/o);


	$f_y = (length($y) == 2) ? sprintf("%02d", $year % 100) : sprintf("%04d", $year);
	$f_m = (length($m) == 1) ? $mon : sprintf("%02d", $mon);
	$f_d = (length($d) == 1) ? $mday : sprintf("%02d", $mday);

	if ($w) {
		$f_w = (length($w) == 1) ? substr($weekday[$wday], 0, 3) : $weekday[$wday];
	}
	if ($j) {
		$f_j = (length($j) == 1) ? $weekday_j[$wday] : "$weekday_j[$wday]曜日";
	}

	$fdate =~ s/$y/$f_y/e;
	$fdate =~ s/$m/$f_m/e;
	$fdate =~ s/$d/$f_d/e;

	$fdate =~ s/$w/$f_w/e;
	$fdate =~ s/$j/$f_j/e;

	return $fdate;

}

# ----------------------------------------------------------------------------- #
# 設定ファイル読込み
# ----------------------------------------------------------------------------- #
sub ReadConfigFile()
{

	# 保存場所、設定情報のリファレンスを貰う。
	my ($Conf, $FORM) = @_;

	open(FH, "$Conf");
	while (<FH>) {
		chomp;
		my ($name, $key, $val) = split(/\t/);
		if ($val) {
			$FORM->{$name}{$key} = $val if(!defined $FORM->{$name}{$key});
		} else {
			$FORM->{$name} = $key if(!defined $FORM->{$name});
		}
	}
	close FH;
}

# ----------------------------------------------------------------------------- #
# カテゴリコンボの作成
# ----------------------------------------------------------------------------- #
sub MakeCateCombo()
{

	my ($cate) = shift;
	my ($cate_combo);

	for my $idx ( 0 .. scalar @CATE) {
		next if (!$CATE[$idx]{NAME});
		my ($def) = ($cate == $idx) ? 'SELECTED' : '';
		$cate_combo .= qq{	<OPTION value="$idx" $def>$CATE[$idx]{NAME}\n};
	}
	return $cate_combo;
}

# ----------------------------------------------------------------------------- #
# 表示形式コンボの作成
# ----------------------------------------------------------------------------- #
sub MakeViewCombo()
{

	my ($view) = shift;
	my ($view_combo, @styles);

	&GetViewList($ViewDir, \@styles);

	for my $idx ( 0 .. scalar @styles ) {
		next if (!defined $styles[$idx]);
		my ($def) = ($view == $idx) ? 'SELECTED' : '';
		$view_combo .= qq{	<OPTION value="$idx" $def>$styles[$idx]{NAME}\n};
	}

	return $view_combo;

}

# ----------------------------------------------------------------------------- #
# 表示用テンプレート一覧取得
# ----------------------------------------------------------------------------- #
sub GetViewList()
{

	my ($DIR, $LIST) = @_;
	my (@DirList);

	opendir(DIR, $DIR);
	@DirList = readdir(DIR);
	closedir(DIR);

	$DIR =~ s/\/$//;

	foreach (@DirList) {
		next if ( $_ =~ /^\.\.?/);

		my ($file) = "$DIR/$_";
		if (-d $file) {
			&GetViewList($file, $LIST);
		} else {
			if(/\.html?$/io) {
				my (%Element);
				push @{$LIST}, \%Element if (&GetViewTemplateInfo($file, \%Element) != 0);
			}
		}
	}
}

# ----------------------------------------------------------------------------- #
# 表示用テンプレート情報取得
# ----------------------------------------------------------------------------- #
sub GetViewTemplateInfo()
{

	my ($File, $VIEW) = @_;

	my ($lines, $title, $flag);

	$VIEW->{FILE} = $File;

	open FH, $File || return;
	while (my $line = <FH>) {
		chomp $line;

		last if ($line =~ /<body/io);

		($title) = $line =~ m/<TITLE>(.*)<\/TITLE>/io;
		last if($title);

		if ($flag == 0 && $line =~ m/<TITLE>/io) {
			$lines .= $line;
			$flag = 1;
		} else {
			if ($flag != 0) {
				$lines .= $line;
				last if ($line =~ m/<\/TITLE>/io);
			}
		}
	}
	close FH;

	if (!$title && $lines) {
		$lines =~ s/<TITLE>|<\/TITLE>|\n|\t//igo;
		$title = $lines;
	}

	$title =~ s/^\s+//o;
	$title =~ s/\s+$//o;

	$VIEW->{NAME} = $title;

	return 1;

}

# ----------------------------------------------------------------------------- #
# 表示用記事データの取得
#
# 【機能】
#	カテゴリ毎の記事管理ファイルより、対象となる記事設定ファイル一覧の作成を行う。
#
# 【引数】
#	$Cate	: 対象カテゴリ
#	$Rows	: 最大件数
#	$Page	: ページ番号
# ----------------------------------------------------------------------------- #
sub MakeNewsList1
{

	my ($Cate, $Rows, $Page) = @_;
	my ($prev, $next);
	my ($count);
	undef @NewsList;

	my $SKIP;
	$Page = ($Page > 1) ? $Page : 1;

	# カテゴリより、ファイル名を作成
	my ($file) = "$CATE[$Cate]{DIR}/cate${Cate}_list.pl";

	if (-f $file) {
		open(IN, "$file") or &Error( 'データファイルのオープンに失敗しました。');

		$skip = $Rows * ($Page - 1);
		$SKIP = $skip;

		$count++ while (<IN>);							# 総数を数える

		$prev = 1 if ($skip > 0);
		$next = 1 if (($Page * $Rows ) < $count);

		my ($lines)	= (($Page * $Rows) <= $count) ? $Rows : $count - $skip;					# 実際に表示される投稿の数 0 < $lines <= $

		seek(IN,0,0);									# ファイルを巻き戻す
		<IN> while($skip--);							# 目的の行まで読み飛ばす
														# 必要なだけ@NewsListに押し込む。
		unshift(@NewsList, scalar(<IN>). "\t$Cate") while($lines-- > 0); 
		close(IN);

	}

	if ($count <=  $Rows ) { $prev = 0; $next = 0; }


	return ($prev, $next);

}

# ----------------------------------------------------------------------------- #
# HTMLへ埋込まれた変数の置換処理
#
# 【機能】
#	HTMLより[@hoge]変数の置換処理を行う。
#
# 【引数】
#	$Lines	: 置換対象
#	$Command: 置換対象ハッシュへのリファレンス
# ----------------------------------------------------------------------------- #
sub ReplaceNewsCommand
{
	my ($Line, $Command) = @_;

	foreach my $key (keys(%{$Command})) {
		if ($Line =~ /$key/i) {
			if ($Line =~ /${key}\{(.*?)\}/i) {
				my ($param) = &Replace($key, $Command, $1);
				$Line =~ s/$key\{(.*?)\}/$param/ie;
			} else {
				$Line =~ s/$key/&Replace($key, $Command)/ige;
			}
		}
	}

	return $Line;
}

# ----------------------------------------------------------------------------- #
# 置換処理
#
# 【機能】
#	%COMMANDへデフォルト値を設定し、埋め込まれた変数の置換を行う。
#
# 【引数】
#	$Key	: 置換対象(@HOGE)
#	$Cmd	: 置換対象ハッシュへのリファレンス
#	$Param	: 個別設定文字列
# ----------------------------------------------------------------------------- #
sub Replace
{

	my ($Key, $Cmd, $Param) = @_;

	my (%ITEM);
	my ($STYLE);

	foreach(keys(%{$Cmd->{$Key}})) {
		$ITEM{$_} = $Cmd->{$Key}{$_} if($Cmd->{$Key}{$_});
	}

	&ConvertStyle(\%ITEM, $ITEM{STYLE});

	$ITEM{NAME}		= $1 if ( $Param =~ m/name\s*?=["'\s]*?([^"'\s]+)["'\s]?/io);
	$ITEM{TYPE}		= $1 if ( $Param =~ m/type\s*?=["'\s]*?([^"'\s]+)["'\s]?/io);
	$STYLE			= $1 if ( $Param =~ m/style\s*?=["']*?([^"']+)["'\s]?/io);
	$ITEM{SRC}		= $1 if ( $Param =~ m/src\s*?=["'\s]*?([^"'\s]+)["'\s]?/io);
	$ITEM{VALUE}	= $1 if ( $Param =~ m/value\s*?=["'\s]*?([^"'\s]+)["'\s]?/io);
	$ITEM{WIDTH}	= $1 if ( $Param =~ m/width\s*?=['"\s]*?([\d%]+)["'\s]?/io);
	$ITEM{HEIGHT}	= $1 if ( $Param =~ m/height\s*?=['"\s]*?([\d%]+)["'\s]?/io);
	$ITEM{ALT}		= $1 if ( $Param =~ m/alt\s*?=["'\s]*?([^"'\s]+)["'\s]?/io);
	$ITEM{BORDER}	= $1 if ( $Param =~ m/border\s*?=['"\s]*?([\d%]+)["'\s]?/io);
	$ITEM{VSPACE}	= $1 if ( $Param =~ m/vspace\s*?=['"\s]*?([\d%]+)["'\s]?/io);
	$ITEM{HSPACE}	= $1 if ( $Param =~ m/hspace\s*?=['"\s]*?([\d%]+)["'\s]?/io);
	$ITEM{ALIGN}	= $1 if ( $Param =~ m/align\s*?=['"\s]*?([\d%]+)["'\s]?/io);
	$ITEM{SIZE}		= $1 if ( $Param =~ m/size\s*?=['"\s]*?([\d]+)["'\s]?/io);

	&ConvertStyle(\%ITEM, $STYLE);

	my ($param);

	if ($ITEM{TYPE} =~ /select/io) {
		$param = qq{<select};
	} else {
		$param = qq{<input type="$ITEM{TYPE}"};
	}

	$param .= qq{ name="$ITEM{NAME}"} if($ITEM{NAME});

	if ($ITEM{TYPE} =~ /image/io) {
		$param .= qq{ SRC="$ITEM{SRC}"} if($ITEM{SRC});
		$param .= qq{ WIDTH="$ITEM{WIDTH}"} if($ITEM{WIDTH});
		$param .= qq{ HEIGHT="$ITEM{HEIGHT}"} if($ITEM{HEIGHT});
		$param .= qq{ ALT="$ITEM{ALT}"} if($ITEM{ALT});
	} else {
		$param .= qq{ value="$ITEM{VALUE}"} if($ITEM{VALUE});
	}

	my ($style);
	$style .= "$_:$ITEM{STYLE_LIST}{$_};" foreach(keys (%{$ITEM{STYLE_LIST}}));
	$param .= qq{ style="$style"} if($style);

	$param .= qq{ onClick="$ITEM{CLICK}"} if($ITEM{CLICK});

	$param .= qq{ $P_PREV} if ($Key =~ /\@PREV_BUTTON/io);
	$param .= qq{ $P_NEXT} if ($Key =~ /\@NEXT_BUTTON/io);

	$param .= qq{ />};

	$param .= qq{$Key</select>} if( $ITEM{TYPE} =~ /select/io);

	return $param;
}

# ----------------------------------------------------------------------------- #
# 置換処理を行うためのデフォルト値の設定を行う。
#
# 【機能】
#	%COMMANDへデフォルト値の設定を行う。
#
# 【引数】
#	$Cmd	: 置換対象ハッシュへのリファレンス
# ----------------------------------------------------------------------------- #
sub SetReplaceCommands
{
	my ($Cmd) = @_;

	$Cmd->{'@PREV_BUTTON'} = {TYPE => 'button', VALUE => '<<前ページ', STYLE => 'cursor:hand;', CLICK => qq{cmdexec('prev')}};
	$Cmd->{'@NEXT_BUTTON'} = {TYPE => 'button', VALUE => '次ページ>>', STYLE => 'cursor:hand;', CLICK => qq{cmdexec('next')}};
	$Cmd->{'@VIEW_BUTTON'} = {TYPE => 'button', VALUE => '表　示', STYLE => 'cursor:hand;', CLICK => qq{cmdexec('view')}};
	$Cmd->{'@SRCH_BUTTON'} = {TYPE => 'button', VALUE => '検　索', STYLE => 'cursor:hand;', CLICK => qq{cmdexec('srch')}};

	$Cmd->{'@WORD'} = {TYPE => 'text', NAME => 'word', VALUE => $FORM{'word'}, SIZE => 5};

	$Cmd->{'@CATE'} = {TYPE => 'select', NAME => 'cate'};
	$Cmd->{'@VIEW'} = {TYPE => 'select', NAME => 'style'};
}

# ----------------------------------------------------------------------------- #
# 置換時のスタイル重複対策
#
# 【機能】
#	%COMMANDへデフォルト値の設定を行う。
#
# 【引数】
#	$Cmd	: 置換対象ハッシュへのリファレンス
# ----------------------------------------------------------------------------- #
sub ConvertStyle
{
	my ($ITEM, $Para) = @_;

	my (@style) = split(/;/, $Para);

	foreach(@style) {
		my ($name, $value) = split(/:/, $_);
		$name =~ s/^ //go;
		$name =~ s/ $//go;
		$ITEM->{STYLE_LIST}{$name} = $value if ($name && $value);
	}

}

# ----------------------------------------------------------------------------- #
# パス変換処理
# ----------------------------------------------------------------------------- #
sub MakePath
{
	my ($FileDir, $File) = @_;

	return $File if ($File =~ /http:\/\//io);

	my ($Path) = "$FileDir/$File";

	$Path =~ s/\/\/+/\//go;		# パスを合成した場合の'//'を'/'へ

	if ($Path =~ m/\.\.\//) {
		my (@Work);
		my ($First) = 1;
		my (@Paths) = split(/\//, $Path);

		foreach my $node (@Paths) {
			next if (!$node || $node eq '.');

			if ($node eq '..' && !$First) {
				pop @Work;
			} else {
				push @Work, $node;
				$First = 0 if ($node ne '..');
			}
		}
		$Path = join('/', @Work);
	}

	$Path =~ s/^http:\/+/http:\/\//io;
	$Path =~ s/\/$//;

	return $Path;

}


# ----------------------------------------------------------------------------- #
# HTMLファイルからイメージ画像の抽出処理
# ----------------------------------------------------------------------------- #
sub ExtractImageFile
{
	my (@html) = @_;
	my (@lists);

	# IMGタグ, <HOGE background>, CSS:background-image より抽出
	foreach my $line (@html) {
		if (my (@imgs) = $line =~ m/<img/io && $line =~ m/src\s*?=\s*?["']?([^\s"'<>\n]+)["'>\n]?/igo) {
			foreach my $img (@imgs) {
				next if(!$img);
				$img =~ s/["']//go;		# 念のため
				push @lists, $img if ($img !~ /^http:\/\//io);
			}
		}

		if (my (@imgs) = $line =~ m/background\s*?=\s*?["']?([^\s"'<>\n]+)["'>\n]?/igo) {
			foreach my $img (@imgs) {
				next if(!$img);
				$img =~ s/["']//go;		# 念のため
				push @lists, $img if ($img !~ /^http:\/\//io);
			}
		}

		if (my (@imgs) = $line =~ m/background-image\s*?:\s*?url\s*?\(\s*?["']?([^\s"'\(\)]+)["']?\s*?\)/igo) {
			foreach my $img (@imgs) {
				next if(!$img);
				$img =~ s/["']//go;		# 念のため
				push @lists, $img if ($img !~ /^http:\/\//io);
			}
		}
	}

	return @lists;

}

# ----------------------------------------------------------------------------- #
# イメージ変換ハッシュの作成
# ----------------------------------------------------------------------------- #
sub MakeImageList
{
	my ($IMG, $Path, @imgs) = @_;

	my @temp;

	foreach my $key (@imgs) {
		next if (exists($IMG->{$key}) );
		$IMG->{$key} = &MakePath($Path, $key);
	}

}


# ----------------------------------------------------------------------------- #
# 構造体の内容表示（デバッグ用）
# ----------------------------------------------------------------------------- #
sub DispStruct
{

	my ($items) = @_;

	print "HTTP/1.0 200 OK\r\n" if $ENV{PERLXS} eq "PerlIS";

print<<EOM;
Content-type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML lang="ja">
<HEAD>
<!---
	<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
--->
	<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=Shift_JIS">
	<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css;">
	<TITLE>エラー</TITLE>
</HEAD>

<BODY>
EOM


	print "---------------------------<BR>\n";

	&DispStructDebug($items, 0);

	print "---------------------------\n";
	print "</BODY>\n</HTML\n>";
	exit;
}

# ----------------------------------------------------------------------------- #
# 構造体の内容表示（デバッグ用）
# ----------------------------------------------------------------------------- #
sub DispStructDebug
{

	my ($items, $idx) = @_;

	if (ref $items eq 'HASH') {
		$idx++;
		foreach my $key ( keys(%{$items})) {
			print "&nbsp;&nbsp;" x $idx;
			print "$key&nbsp;：&nbsp;\n";
			&DispStructDebug($items->{$key}, $idx);
		}
	} elsif (ref $items eq 'ARRAY') {
		$idx++;
		for my $key ( 0 .. $#{$items}) {
			print "&nbsp;" x $idx;
			print "ArrayNo : [$key]<BR>\n";
			&DispStructDebug($items->[$key], $idx);
		}
	} else {
		print "&nbsp;" x $idx;
		print "$items<BR>\n";
	}

}

