#/*
# *  Copyright 2007-2008 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: Draft.pm 1645 2008-02-06 15:40:18Z hikarin $
#

package Img0ch::Plugin::Module::Draft;

use strict;

sub new {
    my ( $iClass, $iKernel ) = @_;
    my $path = $iKernel->get_repos_path('note_draft');

    bless {
        __param => {},
        _kernel => $iKernel,
        _repos  => $iKernel->get_repos($path),
    }, $iClass;
}

sub load {
    my ($iNote) = @_;
    $iNote->{_repos}->load();
    return 1;
}

sub save {
    my ($iNote) = @_;
    my $iRepos  = $iNote->{_repos};
    my $param   = $iNote->{__param};

    if ( keys %$param ) {
        my $count  = $iRepos->get_int('I:P:M:D._') + 1;
        my $last   = $iRepos->get_int('I:P:M:D.max') + 1;
        my $prefix = "I:P:M:D.${last}";
        $iRepos->set( "${prefix}.applet",   $param->{applet} );
        $iRepos->set( "${prefix}.ellapse",  $param->{ellapse} );
        $iRepos->set( "${prefix}.height",   $param->{height} );
        $iRepos->set( "${prefix}.ip",       $param->{ip} );
        $iRepos->set( "${prefix}.modified", $param->{modified} );
        $iRepos->set( "${prefix}.pass",     $param->{pass} );
        $iRepos->set( "${prefix}.type",     $param->{type} );
        $iRepos->set( "${prefix}.width",    $param->{width} );
        $iRepos->set_binary( "${prefix}.animation",
            ${ $param->{animation} } );
        $iRepos->set_binary( "${prefix}.image", ${ $param->{image} } );
        $iRepos->set( 'I:P:M:D._',   $count );
        $iRepos->set( 'I:P:M:D.max', $last );
    }
    $iRepos->save();

    return 1;
}

sub get_count {
    my ($iNote) = @_;
    return $iNote->{_repos}->get_int('I:P:M:D._');
}

sub get_animation {
    my ( $iNote, $id ) = @_;
    return $iNote->{_repos}->get_binary("I:P:M:D.${id}.animation");
}

sub get_image {
    my ( $iNote, $id ) = @_;
    return $iNote->{_repos}->get_binary("I:P:M:D.${id}.image");
}

sub get_image_base64 {
    my ( $iNote, $id ) = @_;
    my $image = $iNote->get_image($id);
    _b64( \$image );
    return $image;
}

sub get_ip {
    my ( $iNote, $id ) = @_;
    return $iNote->{_repos}->get("I:P:M:D.${id}.ip");
}

sub get_ellapse {
    my ( $iNote, $id ) = @_;
    return $iNote->{_repos}->get_int("I:P:M:D.${id}.ellapse");
}

sub get_image_type {
    my ( $iNote, $id ) = @_;
    return $iNote->{_repos}->get("I:P:M:D.${id}.type");
}

sub get_last_modified {
    my ( $iNote, $id ) = @_;
    return $iNote->{_repos}->get_int("I:P:M:D.${id}.modified");
}

sub get_applet_magic {
    my ( $iNote, $id ) = @_;
    return $iNote->{_repos}->get("I:P:M:D.${id}.applet");
}

sub get_edit_pass {
    my ( $iNote, $id ) = @_;
    return $iNote->{_repos}->get("I:P:M:D.${id}.pass");
}

sub get_width {
    my ( $iNote, $id ) = @_;
    return $iNote->{_repos}->get_int("I:P:M:D.${id}.width");
}

sub get_height {
    my ( $iNote, $id ) = @_;
    return $iNote->{_repos}->get_int("I:P:M:D.${id}.height");
}

sub set_ip {
    my ( $iNote, $ip ) = @_;
    $iNote->{__param}->{ip} = $ip;
    return;
}

sub set_image {
    my ( $iNote, $image ) = @_;
    $iNote->{__param}->{image} = $image;
    return;
}

sub set_animation {
    my ( $iNote, $animation ) = @_;
    $iNote->{__param}->{animation} = $animation;
    return;
}

sub set_last_modified {
    my ( $iNote, $modified ) = @_;
    $iNote->{__param}->{modified} = $modified;
    return;
}

sub set_ellapse {
    my ( $iNote, $ellapse ) = @_;
    $iNote->{__param}->{ellapse} = $ellapse;
    return;
}

sub set_image_type {
    my ( $iNote, $type ) = @_;
    $iNote->{__param}->{type} = $type;
    return;
}

sub set_width {
    my ( $iNote, $width ) = @_;
    $iNote->{__param}->{width} = $width;
    return;
}

sub set_height {
    my ( $iNote, $height ) = @_;
    $iNote->{__param}->{height} = $height;
    return;
}

sub set_applet_magic {
    my ( $iNote, $applet ) = @_;
    $iNote->{__param}->{applet} = $applet;
    return;
}

sub set_edit_pass {
    my ( $iNote, $pass ) = @_;
    $iNote->{__param}->{pass} = $pass;
    return;
}

sub remove {
    my ( $iNote, $id ) = @_;
    my $iRepos = $iNote->{_repos};
    my $prefix = "I:P:M:D.${id}";

    if ( $iRepos->remove("${prefix}.modified") ) {
        $iRepos->remove("${prefix}.animation");
        $iRepos->remove("${prefix}.applet");
        $iRepos->remove("${prefix}.ellapse");
        $iRepos->remove("${prefix}.height");
        $iRepos->remove("${prefix}.image");
        $iRepos->remove("${prefix}.ip");
        $iRepos->remove("${prefix}.pass");
        $iRepos->remove("${prefix}.type");
        $iRepos->remove("${prefix}.width");
        $iRepos->set( 'I:P:M:D._', $iRepos->get_int('I:P:M:D._') - 1 );
        return 1;
    }

    return 0;
}

sub purge {
    my ( $iNote, $current_time, $expires_time ) = @_;
    my $iRepos = $iNote->{_repos};
    my $stack  = [];
    my $count  = $iRepos->get_int('I:P:M:D._');
    my $max    = $iRepos->get_int('I:P:M:D.max');
    my $min    = $iRepos->get_int('I:P:M:D.min') || 1;

    for ( my $i = $min; $i <= $max; $i++ ) {
        my $prefix = "I:P:M:D.${i}";
        my $lm     = $iRepos->get_int("${prefix}.modified");
        if ( $current_time > $lm + $expires_time ) {
            $iRepos->remove("${prefix}.animation");
            $iRepos->remove("${prefix}.applet");
            $iRepos->remove("${prefix}.ellapse");
            $iRepos->remove("${prefix}.height");
            $iRepos->remove("${prefix}.image");
            $iRepos->remove("${prefix}.ip");
            $iRepos->remove("${prefix}.pass");
            $iRepos->remove("${prefix}.modified");
            $iRepos->remove("${prefix}.type");
            $iRepos->remove("${prefix}.width");
            $min < $i and $min = $i;
            $count--;
        }
    }

    $count <= 0 and $max = $min = $count = 0;
    $iRepos->set( 'I:P:M:D._',   $count );
    $iRepos->set( 'I:P:M:D.min', $min );
    $iRepos->set( 'I:P:M:D.max', $max );
    $iRepos->save();

    return;
}

sub iterate {
    my ( $iNote, $callback, $argument ) = @_;
    my $iRepos = $iNote->{_repos};
    my $max    = $iRepos->get_int('I:P:M:D.max');
    my $min    = $iRepos->get_int('I:P:M:D.min') || 1;

    for ( my $i = $min; $i <= $max; $i++ ) {
        my $prefix = "I:P:M:D.${i}";
        my $image  = $iRepos->get("${prefix}.image");
        _b64( \$image );
        my $hash = {
            animation => $iRepos->get("${prefix}.animation"),
            applet    => $iRepos->get("${prefix}.applet"),
            ellapse   => $iRepos->get_int("${prefix}.ellapse"),
            height    => $iRepos->get_int("${prefix}.height"),
            id        => $i,
            image     => $image,
            ip        => $iRepos->get("${prefix}.ip"),
            pass      => $iRepos->get("${prefix}.pass"),
            modified  => $iRepos->get_int("${prefix}.modified"),
            type      => $iRepos->get("${prefix}.type"),
            width     => $iRepos->get_int("${prefix}.width"),
        };
        $callback->( $hash, $argument );
    }

    return;
}

sub _b64 {
    my ($image) = @_;
    if ( $$image !~ /\A[\w\/\+\=]+\z/xms ) {
        if ( defined $MIME::Base64::VERSION
            or eval 'require MIME::Base64; 1' )
        {
            $$image = MIME::Base64::encode_base64($$image);
        }
        else {
            defined $MIME::Base64::Perl::VERSION
                or require MIME::Base64::Perl;
            $$image = MIME::Base64::Perl::encode_base64($$image);
        }
    }
    return;
}

1;
__END__
