# vim: set cindent expandtab ts=4 sw=4:
#
# Copyright (c) 1998-2005 Chi-Keung Ho. All rights reserved.
#
# This programe is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# Extmail - a high-performance webmail to maildir
# $Id$
package Ext::App::Abook;
use strict;
use Exporter;

use vars qw(@ISA @EXPORT);
@ISA = qw(Exporter Ext::App);
use Ext::App;
use Ext::Abook;
use Ext::Utils qw(myceil reset_working_path);
use Ext::MIME; # import html_fmt()
use Encode::PPUniDetector;
use Ext::Unicode::Iconv qw(iconv);

use vars qw(%lang_abook $lang_charset);
use Ext::Lang;

sub init {
    my $self = shift;
    $self->SUPER::init(@_);
    return unless($self->valid||$self->permit);

    $self->add_methods(abook_show => \&abook_show);
    $self->add_methods(abook_edit => \&abook_edit);
    $self->add_methods(abook_export => \&abook_export);
    $self->add_methods(abook_search => \&abook_search);

    $self->{default_mode} = 'abook_show';
    Ext::Storage::Maildir::init($self->get_working_path);

    $self->_initme;
    $self;
}

sub _initme {
    initlang($_[0]->userconfig->{lang}, __PACKAGE__);
    $_[0]->{tpl}->assign( lang_charset => $lang_charset );
    $_[0]->{tpl}->assign( \%lang_abook );
}

sub abook_export {
    my $self = shift;
    print "Content-Disposition: attachment; filename=\"abook.csv\"\r\n";
    print "Content-Type: text/plain; name=\"abook.csv\"\r\n\r\n";
    open(FD, "< abook.cf"); # ignore error;
    local $/ = undef;
    my $buf = <FD>;
    close FD;

    # convert abook from utf8 to local encoding if it's convertable
    my $rv = Encode::PPUniDetector::trylocal2($buf, intl2euc($self->userconfig->{lang}));
    if ($rv && uc $rv ne 'UTF-8') {
        $buf = iconv($buf, 'utf-8', $rv);
    }

    print $buf;
    $self->{tpl}->{noprint} = 1;
}

sub abook_show {
    my $self = shift;
    my $tpl = $self->{tpl};
    my $q = $self->{query};
    my $mode = $_[0];
    my $page = $q->cgi('page') || 0;
    my $show_all = $q->cgi('show_all') ? 1:0;
    my $size = $self->userconfig->{page_size} || 10;
    my $obj = Ext::Abook->new(file=>'abook.cf');
    my $abook = $obj->sort;
    my $maxpages = myceil((scalar @$abook -1)/$size); # total number

    $page = ($page >=0 ? ($page > $maxpages -1 ? $maxpages -1 : $page) : 0);

    $tpl->assign(
        # the nums of abook should >1, for the first member is
        # header fields
        HAVE_ABOOK => (scalar @$abook>1?1:0),
        SID => $self->{sid},
        CUR_PAGE => $page,
    );

    my $_end = ($page+1)*$size + 1;
    my $start = $show_all? 1 : $page*$size + 1;
    my $end = $show_all ? scalar @$abook : (scalar @$abook >=$_end ? $_end : scalar @$abook);

    foreach(my $k=$start; $k< $end; $k++) {
        my $e = $abook->[$k];
        $tpl->assign(
            'LOOP_ABOOK',
            ID => $e->[0],          # line ID
            NAME => $e->[1],        # 0
            MAILADDR => $e->[2],    # 1
            COMPANY => $e->[3],     # 2
            MOBILE => $e->[4]       # 3
        );
    }

    return if $show_all;

    $tpl->assign(
        HAVE_PREV => ($page >0? 1:0),
        HAVE_NEXT => ($page< $maxpages-1?1:0),
        PREV => ($page>0?$page-1:0),
        NEXT => ($page<$maxpages-1?$page+1:$maxpages),
    );

    unless($mode) {
        $tpl->assign(
            EDIT_NAME => $q->cgi('name'),
            EDIT_MAILADDR => $q->cgi('mail'),
            EDIT_COMPANY => $q->cgi('company'),
            EDIT_MOBILE => $q->cgi('mobile')
        );
    }

    # return url support
    if($q->cgi('url')) {
        $tpl->assign( RETURN_URL => $q->cgi('url') );
    }
}

sub abook_edit {
    my $self = shift;
    my $q = $self->{query};
    my $tpl = $self->{tpl};
    my $obj = Ext::Abook->new(file =>'abook.cf');

    my $name = $q->cgi('name');
    my $mail = $q->cgi('mail');
    my $com = $q->cgi('company');
    my $mobile = $q->cgi('mobile');

    if($q->cgi('newabook')) {
        $obj->append([$name,$mail,$com,$mobile]);
        $obj->save;
        if($q->cgi('url')) {
            $tpl->{noprint} = 1;
            $self->{redirect} = $q->cgi('url');
        }
    }elsif($q->cgi('editsave')) {
        my $curid = $q->cgi('CURID');
        if($curid ne "" && $curid>0) {
            $obj->update($q->cgi('CURID'), [$name,$mail,$com,$mobile]);
            $obj->save;
        }
    }elsif($q->cgi('delete')) {
        my $a = $q->cgi_full_names;
        my @ids = grep { s/^REMOVE-// } @$a; # get ids
        $obj->delete(@ids);
        $obj->save;
    }elsif($q->cgi('edit')) {
        my $a = $q->cgi_full_names;
        my ($id) = grep { s/^REMOVE-// } @$a; # get id
        my $s = '';
        if ($id >0 ) {
            $s = $obj->lookup($id);
        } else {
            # do nothing
            $self->abook_show;
            return;
        }

        $tpl->assign(
            MODE_EDIT => 1,
            CURID => $id,
            EDIT_NAME => html_fmt($s->[0]),
            EDIT_MAILADDR => html_fmt($s->[1]),
            EDIT_COMPANY => html_fmt($s->[2]),
            EDIT_MOBILE => html_fmt($s->[3])
        );
    }
    $self->abook_show('edit');
}

sub abook_search {
    my $self = shift;
    my $tpl = $self->{tpl};
    my $q = $self->{query};
    my $obj = Ext::Abook->new(file=>'abook.cf');

    my $key = $q->cgi('keyword');
    my @ids = $obj->search($key);

    if(scalar @ids) {
        $tpl->assign( HAVE_ABOOK => 1, KEYWORD => $key );
    }else {
        $tpl->assign( SEARCH_NULL => 1 );
        return 0;
    }

    my $size = $self->userconfig->{page_size};
    my $page = $q->cgi('page') || 0;
    my $maxpages = myceil(scalar @ids/$size);

    $page = ($page >=0 ? ($page > $maxpages -1 ? $maxpages -1 : $page) : 0);

    my $_end = ($page+1)*$size;
    my $start = $page*$size;
    my $end = scalar @ids >=$_end ? $_end : scalar @ids;

    $tpl->assign(
        CUR_PAGE => $page,
        HAVE_PREV => ($page >0? 1:0),
        HAVE_NEXT => ($page< $maxpages-1?1:0),
        PREV => ($page>0?$page-1:0),
        NEXT => ($page<$maxpages-1?$page+1:$maxpages),
    ); 

    for (my $id=$start;$id<$end;$id++) {
        my $e = $obj->lookup($ids[$id]);
        $tpl->assign(
            'LOOP_ABOOK',
            ID => $ids[$id], # real id
            NAME => $e->[0],
            MAILADDR => $e->[1],
            COMPANY => $e->[2],
            MOBILE => $e->[3]
        );
    }
}

sub pre_run { 1 }

sub post_run {
    my $template = $_[0]->{query}->cgi('screen') || 'abook.html';
    reset_working_path();
    $_[0]->{tpl}->process($template);
    $_[0]->{tpl}->print;
}

1;


syntax highlighted by Code2HTML, v. 0.9.1