#/*
# *  Copyright 2007-2009 hkrn <hikarin@users.sourceforge.jp>
# *
# *  Licensed under the Apache License, Version 2.0 (the "License");
# *  you may not use this file except in compliance with the License.
# *  You may obtain a copy of the License at
# *
# *      http://www.apache.org/licenses/LICENSE-2.0
# *
# *  Unless required by applicable law or agreed to in writing, software
# *  distributed under the License is distributed on an "AS IS" BASIS,
# *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# *  See the License for the specific language governing permissions and
# *  limitations under the License.
# */
#
# $Id: Setting.pm 1826 2009-04-08 15:23:25Z hikarin $
#

package Img0ch::Setting;

use strict;

sub new {
    my ( $iClass, $iBBS ) = @_;
    my $iKernel = $iBBS->get_kernel();

    my $iReposCommon = $iBBS->get_common_repos();
    my $iReposSystem = $iBBS->get_system_repos();
    if ( $iKernel->get_config()->get('compatible.setting') ) {
        require Img0ch::Compat::Setting;
        Img0ch::Compat::Setting::load( $iReposSystem, $iBBS );
    }

    my $bbs = $iBBS->get_name();
    bless {
        __all     => 0,
        _bbs      => $iBBS->get_name(),
        __cache   => {},
        _common   => $iReposCommon,
        _encoding => $iBBS->get_encoding(),
        _kernel   => $iKernel,
        __path    => $iBBS->path('SETTING.TXT'),
        _system   => $iReposSystem,
        _utf8     => $iBBS->is_utf8(),
    }, $iClass;
}

sub load {
    my ($iSetting) = @_;
    $iSetting->{_common}->load();
    $iSetting->{_system}->load();
    return 1;
}

sub flush {
    $_[1]
        ? delete( $_[0]->{__cache}->{ $_[1] } )
        : ( %{ $_[0]->{__cache} } = () );
}

sub get {
    my ( $iSetting, $key ) = @_;
    my $cache = $iSetting->{__cache};
    exists $cache->{$key} and return $cache->{$key};

    my $iReposSystem = $iSetting->{_system};
    my $bbs          = $iSetting->{_bbs};
    my $utf8         = $iReposSystem->get("I:S.${bbs}.utf8");
    my $value;

    # >= 2.1.27 and board uses Shift_JIS
    if ( !$iSetting->{_utf8} and $utf8 ) {
        $value
            = $iSetting->{_kernel}
            ->get_encoded_str( $iReposSystem->get("I:S.${bbs}.${key}"),
            $iSetting->{_encoding}, 'utf8', );
    }

    # < 2.1.27
    elsif ( !$utf8 ) {
        $value = $iSetting->{_kernel}->get_encoded_str(
            $iReposSystem->get("I:S.${bbs}.${key}")
                || $iSetting->{_common}->get("I:S.${bbs}.${key}"),
            $iSetting->{_encoding}, 'sjis',
        );
    }

    # >= 2.1.27 and board uses UTF-8
    else {
        $value = $iReposSystem->get("I:S.${bbs}.${key}");
    }

    $iSetting->{__cache}->{$key} = $value;
}

sub get_utf8 {
    my ( $iSetting, $key ) = @_;
    my $value = $iSetting->get($key);
    return $iSetting->{_kernel}
        ->get_encoded_str( $value, 'utf8', $iSetting->{_encoding} );
}

sub set {
    my ( $iSetting, $key, $value ) = @_;
    $iSetting->{__cache}->{$key} = $value;
    return;
}

sub get_hash {
    my ($iSetting)   = @_;
    my $iReposCommon = $iSetting->{_common};
    my $iReposSystem = $iSetting->{_system};
    my $ret          = {};

    if ( $iSetting->{__all} ) {
        %{$ret} = %{ $iSetting->{__cache} };
    }
    else {
        my $count = $iReposCommon->get_int('I:S._');
        for ( my $i = 0; $i < $count; $i++ ) {
            my $key = $iReposCommon->get("I:S.${i}");
            $ret->{$key} = $iSetting->get($key);
        }
        $iSetting->{__all} = 1;
    }
    $ret;
}

sub get_int { Img0ch::Kernel::intval( $_[0]->get( $_[1] ) ) }

sub is_checked { $_[0]->get( $_[1] ) eq 'checked' ? 1 : 0 }

sub path { $_[0]->{__path} }

1;
__END__

=head1 NAME

Img0ch::Setting - 掲示板設定を収めたファイルであるSETTING.TXTを管理するクラス

=head1 SYNOPSYS

  use Img0ch::Setting

  my $iSetting = Img0ch::Setting->new($iBBS);
  $iSetting->load();

  # BBS_TITLEの値を取り出す
  my $bbs_title = $iSetting->get('BBS_TITLE');
  # timecountの値を数値として取り出す
  my $timecount = $iSetting->get_int('timecount');
  # NANASHI_CHECKが入っているかどうかを調べる
  my $no_nanashi = $iSetting->is_checked('NANASHI_CHECK');

=head1 DESCRIPTION

掲示板単体のSETTING.TXTを1つのオブジェクトとするクラスです。

=head2 new

=over 4

=item Arguments

$iBBS (Img0ch::BBS)

=item Return Value

$iSetting (Img0ch::Setting itself)

=back

I<Img0ch::Setting>のオブジェクトを作成します。

=head2 load

=over 4

=item Arguments

none

=item Return Value

1

=back

SETTING.TXTを読み込みます。

=head2 flush

=over 4

=item Arguments

$key?

=item Return Value

$old_value

=back

I<get()>、I<get_int()>、I<is_checked()>を呼び出したときに
使用されるキャッシュを削除します。I<$key>が指定された場合
I<$key>に対応する値を返します。
引数が指定されなかった場合は全てのキャッシュを削除します。

=head2 get

=over 4

=item Arguments

$key

=item Return Value

$string_of_value

=back

指定されたSETTING.TXTの値を文字列として取り出します。
未定義の場合ナルストリングが返されます。
二回目に呼び出されたときは一回目に呼び出したときにキャッシュした値を返します。

=head2 get

=over 4

=item Arguments

$key

=item Return Value

$string_of_value_utf8_encoded

=back

値がUTF8で返される点以外はI<get()>と同様です。

=head2 set

=over 4

=item Arguments

$key, $value

=item Return Value

none

=back

指定されたSETTING.TXTの値をオブジェクト内部のキャッシュに設定します。
このため、指定された値はオブジェクトが生存する限り有効です。

=head2 get_hash

=over 4

=item Arguments

none

=item Return Value

$reference_to_setting_hash

=back

全てのSETTING.TXTの値を取り出し、ハッシュのリファレンスとして返します。
I<Img0ch::Template>でのみ使用されます。

=head2 get_int

=over 4

=item Arguments

$key

=item Return Value

$integer_of_value

=back

指定されたSETTING.TXTの値を数値として取り出します。
未定義の場合0が返されます。
二回目に呼び出されたときは一回目に呼び出したときにキャッシュした値を返します。

=head2 is_checked

=over 4

=item Arguments

$key

=item Return Value

1 (checked) or 0

=back

指定されたSETTING.TXTの値がI<checked>であるかを調べます。
二回目に呼び出されたときは一回目に呼び出したときにキャッシュした値を返します。

=head2 path

=over 4

=item Arguments

none

=item Return Value

$path_to_settting_txt

=back

SETTING.TXTのパスを返します。

=head1 AUTHOR

hkrn E<lt>hikarin@users.sourceforge.jpE<gt>

=cut
