#/*
# *  Copyright 2007 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: Icon.pm 802 2007-06-10 12:47:54Z hikarin $
#

package Zeromin::Icon;

use strict;
use base qw(Img0ch::Icon);

sub save {
    my ($iIcon) = @_;
    my $iRepos  = $iIcon->{_repos};
    my $icons   = $iIcon->{__icons};

    if ( scalar @$icons ) {
        my $count = $iIcon->{_count};
        for my $icon (@$icons) {
            my $prefix = 'I:I.' . $icon->{id};
            $iRepos->get("${prefix}.name") or $count++;
            $iRepos->set( "${prefix}.description",
                       $icon->{description}
                    || $iRepos->get("${prefix}.description") );
            $iRepos->set( "${prefix}.extension",
                $icon->{extension} || $iRepos->get("${prefix}.extension") );
            $iRepos->set( "${prefix}.is_global",
                       $icon->{is_global}
                    || $iRepos->get_int("${prefix}.is_global") );
            $iRepos->set( "${prefix}.height",
                $icon->{height} || $iRepos->get_int("${prefix}.height") );
            $iRepos->set( "${prefix}.name",
                $icon->{name} || $iRepos->get("${prefix}.name") );
            $iRepos->set( "${prefix}.pass",
                $icon->{pass} || $iRepos->get("${prefix}.pass") );
            $iRepos->set( "${prefix}.width",
                $icon->{width} || $iRepos->get_int("${prefix}.width") );
        }
        $iIcon->{_count} = $count;
        $iRepos->set( 'I:I._', $count );
    }

    $iRepos->save();
    $iIcon->update_csv();
    return 1;
}

sub set {
    my ( $iIcon, $id, $info ) = @_;
    $id or return;
    push @{ $iIcon->{__icons} },
        {
        description => ( $info->{description} || '' ),
        extension   => ( $info->{extension}   || '' ),
        height    => Img0ch::Kernel::intval( $info->{height} ),
        id        => $id,
        is_global => Img0ch::Kernel::intval( $info->{is_global} ),
        name      => ( $info->{name} || '' ),
        pass      => ( $info->{pass} || '' ),
        width     => Img0ch::Kernel::intval( $info->{width} ),
        };
    return;
}

sub search {
    my ( $iIcon, $path, $url ) = @_;
    my $count = 0;
    $count += $iIcon->_search( $path, 1 );
    $count += $iIcon->_search( join( '/', $path, $iIcon->{_bbs} ), 0 );
    $iIcon->save();
    $iIcon->update_csv();
    return $count;
}

sub _search {
    my ( $iIcon, $path, $global ) = @_;
    my $iKernel = $iIcon->{_kernel};
    -d $path or return 0;
    $global ||= 0;

    local ( *DH, $/ );
    opendir *DH, $path or $iKernel->throw_io_exception($path);
    my @icons = readdir *DH;
    closedir *DH or $iKernel->throw_io_exception($path);

    require File::Spec;
    require Img0ch::Upload;
    my $count = 0;
    for my $icon ( File::Spec->no_upwards(@icons) ) {
        $icon =~ /\A\w+\.\w+\z/xms or next;
        my $icon_path = File::Spec->catfile( $path, $icon );
        -r $icon_path or next;
        my ( $width, $height ) = Img0ch::Upload->get_dimensions($icon_path);
        $icon =~ s/\.(\w+)\z//xms;
        my $extension = $1;
        if ( !$iIcon->get($icon)->{extension} and $width and $height ) {
            $iIcon->set(
                $icon,
                {   name      => $icon,
                    extension => $extension,
                    is_global => $global,
                    width     => $width,
                    height    => $height,
                }
            );
            $count++;
        }
    }
    return $count;
}

sub update_csv {
    my ($iIcon) = @_;
    my $iKernel = $iIcon->{_kernel};
    my $path    = $iIcon->path();
    my $temp    = $path . '.tmp';
    my $LOCK_EX = 2;

    eval {
        require Fcntl;
        $LOCK_EX = Fcntl::LOCK_EX();
    };
    eval {
        local ( $!, *FH );
        require Unicode::Japanese;
        open *FH, ">${temp}"    ## no critic
            or $iKernel->throw_io_exception($path);
        flock *FH, $LOCK_EX;
        my $count = 0;
        my $unijp = Unicode::Japanese->new();
        for my $icon ( @{ $iIcon->to_array() } ) {
            print {*FH} $unijp->join_csv(
                $icon->{id},        $icon->{extension},
                $icon->{width},     $icon->{height},
                $icon->{is_global}, $icon->{name},
                $icon->{description}
                )->get()
                or $iKernel->throw_io_exception($path);
        }
        close *FH or $iKernel->throw_io_exception($path);
        rename $temp, $path or $iKernel->throw_io_exception($path);
    };
    if ( my $exception = $@ ) {
        unlink $temp or $iKernel->throw_io_exception($temp);
        die $exception, "\n";
    }

    return 1;
}

sub remove {
    my ( $iIcon, $id ) = @_;
    my $iRepos = $iIcon->{_repos};
    if ( $iRepos->remove("I:I.${id}.name") ) {
        $iRepos->remove("I:I.${id}.description");
        $iRepos->remove("I:I.${id}.extension");
        $iRepos->remove("I:I.${id}.is_global");
        $iRepos->remove("I:I.${id}.height");
        $iRepos->remove("I:I.${id}.pass");
        $iRepos->remove("I:I.${id}.width");
        $iRepos->set( 'I:I._', --$iIcon->{_count} );
        return 1;
    }
    return 0;
}

1;
__END__
