###############################################################################
#
# InterWikiNameのパーサ
#
###############################################################################
package Wiki::InterWiki;
use strict;

#==============================================================================
# コンストラクタ
#==============================================================================
sub new {
	my $class = shift;
	my $wiki  = shift;
	my $self  = {};

	$self->{wiki} = $wiki;
	$self->{interwiki} = [];
	bless $self,$class;

	$self->_parse();
	$self->_add_children($wiki);

	return bless $self;
}

#==============================================================================
# 子WikiをInterWikiに追加
#==============================================================================
sub _add_children {
	my $self = shift;
	my $wiki = shift;

	eval {
		my @children = $wiki->get_wiki_list();
		$self->_add_child($wiki,"",@children);
	}
}
#==============================================================================
# 子WikiをInterWikiに追加(再帰的にcallされるメソッド)
#==============================================================================
sub _add_child {
	my $self   = shift;
	my $wiki   = shift;
	my $parent = shift;
	my @items  = @_;
	my $prev   = "";

	foreach my $item (@items){
		if(ref($item) eq "ARRAY"){
			if($parent eq ""){
				$self->_add_child($wiki,"$prev",@$item);
			} else {
				$self->_add_child($wiki,"$parent/$prev",@$item);
			}
		} else {
			if($parent eq ""){
				$self->add_inter_wiki($wiki->config('script_name')."/$item?page=","$item");
			} else {
				$self->add_inter_wiki($wiki->config('script_name')."/$parent/$item?page=","$parent/$item");
			}
			$prev = $item;
		}
	}
}

#==============================================================================
# パース(コンストラクタから呼ばれます)
#==============================================================================
sub _parse {
	my $self = shift;
	my $wiki = $self->{wiki};
	if($wiki->page_exists("InterWikiName")){
		my $source = $wiki->get_page("InterWikiName");
		$source =~ s/\r//g;
		my @lines = split(/\n/,$source);
		foreach my $line (@lines){
			if(index($line,"*")==0){
				$self->_parse_line($line);
			}
		}
	}
}

#==============================================================================
# 1行をパース
#==============================================================================
sub _parse_line {
	my $self   = shift;
	my $source = shift;
	# 別名リンク
	if($source =~ /\[([^\[]+?)\|((http|https|ftp|mailto):[\w\.,%~^+\-%\/\?\(\)!\$&=:;\*#\@']*)\]\s*([\w\-]+)/
	    ||  $source =~ /\[([^\[]+?)\|((file:[^\[\]]*))\]\s*([\w\-]+)/
	    ||  $source =~ /\[([^\[]+?)\|((\/|\.\/|\.\.\/)+[\w\.,%~^+\-%\/\?\(\)!\$&=:;\*#\@']*)\]\s*([\w\-]+)/){
		my $label = $1;
		my $url   = $2;
		my $enc   = $4;
		$self->add_inter_wiki($url,$label,$enc);

	# 文字コードの指定なし
	} elsif($source =~ /\[([^\[]+?)\|((http|https|ftp|mailto):[a-zA-Z0-9\.,%~^_+\-%\/\?\(\)!\$&=:;\*#\@']*)\]/
	    ||  $source =~ /\[([^\[]+?)\|(file:[^\[\]]*)\]/
	    ||  $source =~ /\[([^\[]+?)\|((\/|\.\/|\.\.\/)+[a-zA-Z0-9\.,%~^_+\-%\/\?\(\)!\$&=:;\*#\@']*)\]/){
		my $label = $1;
		my $url   = $2;
		my $enc   = "";
		$self->add_inter_wiki($url,$label,$enc);

	# 任意のURLリンク
	} elsif($source =~ /\[([^\[]+?)\|(.+?)\]\s*([\w\-]+)/){
		my $label = $1;
		my $url   = $2;
		my $enc   = $3;
		$self->add_inter_wiki($url,$label,$enc);

	# 任意のURLリンク(文字コードの指定なし)
	} elsif($source =~ /\[([^\[]+?)\|(.+?)\]/){
		my $label = $1;
		my $url   = $2;
		my $enc   = "";
		$self->add_inter_wiki($url,$label,$enc);

	}
}

#==============================================================================
# InterWikiNameを追加
#==============================================================================
sub add_inter_wiki {
	my $self  = shift;
	my $url   = shift;
	my $label = shift;
	my $enc   = shift;

	push(@{$self->{interwiki}},{label=>$label,quote=>quotemeta($label),url=>$url,enc=>$enc});
}

#==============================================================================
# InterWikiNameが含まれるかどうかチェック
#==============================================================================
sub exists_interwiki {
	my $self = shift;
	my $str  = shift;

	my @keywords = @{$self->{interwiki}};

	foreach my $keyword (@keywords){
		my $label = $keyword->{quote};

		if($str =~ /\[\[$label:(.+?)\]\]/){
			$self->{g_pre}   = $`;
			$self->{g_post}  = $';
			my $enc   = $keyword->{enc};
			my $param = $1;
			$self->{g_label} = $keyword->{label}.":".$param;
			if($enc ne ""){
				&Jcode::convert(\$param,$enc);
			}
			$self->{g_url} = $keyword->{url}.Util::url_encode($param);
			return 1;

		} elsif($str =~ /\[\[([^\[]+?)\|$label:(.+?)\]\]/){
			$self->{g_pre}   = $`;
			$self->{g_post}  = $';
			$self->{g_label} = $1;
			my $enc   = $keyword->{enc};
			my $param = $2;
			if($enc ne ""){
				&Jcode::convert(\$param,$enc);
			}
			$self->{g_url} = $keyword->{url}.Util::url_encode($param);
			return 1;
		}
	}
	return 0;
}

1;