# Copyright (C) 2006 Affelio inc.
#
# This program 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.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.


package Diary::WriteDiary;
{
use strict;
use Jcode;
use LWP::UserAgent;
use HTTP::Request::Common qw(POST);
use File::Copy;
use Time::Local;

use Affelio::misc::Debug qw( debug_print);

use Exporter;
@Diary::WriteDiary::ISA = "Exporter";
@Diary::WriteDiary::EXPORT = qw (show handler);


    #######################################################################
    #handler
    #######################################################################
    sub handler{
	my $cgi = shift;
	my $diary = shift;
	my $out_ref = shift;
	
	debug_print("Diary::Write::handler: start.");

	###############################
	#normal show
	###############################
	show($diary, $cgi, $out_ref);
	debug_print("Diary::Write::handler: end.");
    }

    #######################################################################
    #show
    #######################################################################    
    sub show{
	my $diary= shift;
	my $cgi=shift;
	my $output_ref = shift;
	debug_print("Diary::Write::show start.");

	my $wi = new Affelio::misc::WebInput();
	my $sub_mode = $wi->PTN_mode($cgi->param("action"));
	my $delete = $cgi->param("delete");
	my $title = $diary->escape($cgi->param("title"));
	my $contents = $diary->escape($cgi->param("contents"));
	my $category = $wi->PTN_num($cgi->param("category"));
	my $tping = $wi->PTN_URL($cgi->param("tping_url"));
	my $id = $wi->PTN_num($cgi->param("id"));
	my $min = $wi->PTN_num($cgi->param("min"));
	my $hour = $wi->PTN_num($cgi->param("hour"));
	my $mday = $wi->PTN_num($cgi->param("mday"));
	my $mon = $wi->PTN_num($cgi->param("mon"));
	my $year = $wi->PTN_num($cgi->param("year"));
    
	###############################
	#arg
	###############################
	try{
	    if( ($sub_mode eq "edit") && ($id)){
		my $tmp_imgdir = "$diary->{datadir}tmp/";
		my $tmp_thumbdir = "$diary->{datadir}tmp/thumb/";
		removeFiles($diary,$tmp_imgdir);
		removeFiles($diary,$tmp_thumbdir);
	
		copyFiles($diary,$id);
		$output_ref->{tmpl_file} = $diary->{afap}->{app__fs_root}."/templates/write_diary_edit.tmpl";
		my $entry = getEntry($diary,$id);
		$output_ref->{"EDIT"} = '1';
		$output_ref->{"ID"} = $id;
		$output_ref->{"TITLE"} = $entry->{"title"};
		$output_ref->{"CONTENTS"} = $diary->br2n($entry->{"contents"});
		(my $sec, $output_ref->{min}, $output_ref->{hour}, $output_ref->{mday}, $output_ref->{mon}, $output_ref->{year}) = localtime($entry->{"timestamp"});
		$output_ref->{mon}++;
		$output_ref->{year} += 1900;
		debug_print("Diary::Write::show:edit get category");
		my @categories = $diary->getall("SELECT id, category FROM $diary->{category_table}");
		debug_print("Diary::Write::show: num of category $#categories");
		if ($#categories >= 0) {
		    foreach(@categories){
			if ($entry->{c_id} == $_->{id}){
			    $_->{SELECT} = '1';
			}else{
			    $_->{SELECT} = '0';
			}
		    }
		    $output_ref->{"CATEGORIES"}= \@categories;
		}

	    }elsif( $sub_mode eq "update" && ($id) ){
		if ($delete){
		    # delete entry
		    debug_print("Diary::Write::show: before delete entry");
		    $diary->{dbh}->do("DELETE FROM $diary->{entry_table} WHERE id = $id");
		    $diary->{dbh}->do("DELETE FROM $diary->{comment_table} WHERE id = $id");
		    $diary->{dbh}->do("DELETE FROM $diary->{tb_table} WHERE id = $id");
		    if (-f $diary->{datadir}."$id.stor") {
			unlink $diary->{datadir}."$id.stor";
		    }
		    removeUploadedImage($diary,$id);

		    $output_ref->{tmpl_file} = $diary->{afap}->{app__fs_root}."/templates/write_diary_done.tmpl";
		    $output_ref->{"DELETE"}='1';
		    debug_print("Diary::Write::show: after delete entry");
		}else{
		    # update entry
		    debug_print("Diary::Write::show: before update entry");
		    my $time = timelocal(0, $min, $hour, $mday, $mon - 1, $year);
		    updateEntry($diary, $id, $title, $contents, $category, $time);
		    copyUploadImage($diary, $id);
		    # send trackback ping
		    debug_print("Diary::Write::show: ping");
		    if ($tping) {
			sendTrackbackPing($diary, $tping, $title, $contents, $id);
		    }
		    $output_ref->{tmpl_file} = $diary->{afap}->{app__fs_root}."/templates/write_diary_done.tmpl";
		}
	    }
	    elsif( $sub_mode eq "submit" ){
		# add entry
		debug_print("Diary::Write::show: before add entry");
		my $time = timelocal(0, $min, $hour, $mday, $mon - 1, $year);
		my $new_id = addEntry($diary, $title, $contents, $category,$time);
		copyUploadImage($diary, $new_id);
		debug_print("Diary::Write::show: post news");
		$diary->{afap}->post_news($title, 
				 "", 
				 $diary->{afap}->get_visitor_info("nickname"),
				 $diary->{afap}->get_site_info("web_root") . "/apps/". 
				 $diary->{afap}->{install_name} . "/list_diary.cgi");
	
		debug_print("Diary::Write::show: ping");
		# send trackback ping
		if ($tping) {
		    sendTrackbackPing($diary, $tping, $title, $contents, $new_id);
		}
		debug_print("Diary::Write::show: load tmpl");
		
		$output_ref->{tmpl_file} = $diary->{afap}->{app__fs_root}."/templates/write_diary_done.tmpl";
		debug_print("Diary::Write::show: after submit");
	    }else{
		(my $sec, $output_ref->{min}, $output_ref->{hour}, $output_ref->{mday}, $output_ref->{mon}, $output_ref->{year}) = localtime;
		$output_ref->{mon}++;
		$output_ref->{year} += 1900;
		my $tmp_imgdir = "$diary->{datadir}tmp/";
		my $tmp_thumbdir = "$diary->{datadir}tmp/thumb/";
		removeFiles($diary,$tmp_imgdir);
		removeFiles($diary,$tmp_thumbdir);
	
		$output_ref->{tmpl_file} = $diary->{afap}->{app__fs_root}."/templates/write_diary_edit.tmpl";
		$output_ref->{"TITLE"} = $diary->escape($title);
		$output_ref->{"CONTENTS"} = $diary->escape($contents);
		debug_print("Diary::Write::show: get category");
		my @categories = $diary->getall("SELECT id, category FROM $diary->{category_table}");
		debug_print("Diary::Write::show: num of category $#categories");
		if ($#categories >= 0) {
		    $output_ref->{"CATEGORIES"}= \@categories;
		}
	    }
	}catch Error with{
	    my $e = shift;
	    $output_ref->{err_msg} .= $e->stacktrace . '<BR>';
	};

	debug_print("Diary::Write::show end.");
    }

    ##############################################
    # addEntry
    ##############################################

    sub addEntry {
	my $diary     = shift;
	my $title    = shift;
	my $contents = shift;
	my $c_id = shift;
	my $user = $diary->{nickname};
	my $uri = $diary->{afid};
	my $pwd;
	my $time     = shift;
	debug_print("Diary::Write::addEntry: start.");
	unless ($time) { $time = time; }

	my ($sec, $min, $hour, $mday, $mon, $year) = localtime($time);
	$year += 1900; $mon += 1;
	if ($c_id eq ""){ $c_id = "NULL";}
	debug_print("Diary::Write::addEntry: prevent double submit.");
	# prevent double submit
	my @same = $diary->getall("SELECT id FROM $diary->{entry_table} WHERE title = '$title' AND contents = '$contents'");
	if($#same >= 0) { return; }

	debug_print("Diary::Write::addEntry: insert new entry.");
	$diary->{dbh}->do("INSERT INTO $diary->{entry_table} VALUES (NULL, '$title', '$contents', $year, $mon, $mday, $time, $c_id, '$user', '$uri', NULL, 0)");

	my $id = $diary->getColumn("SELECT MAX(id) FROM $diary->{entry_table}");
	return $id;
}

##############################################
# updateEntry
##############################################
sub updateEntry {
	my $diary    = shift;
	my $id       = shift;
	my $title    = shift;
	my $contents = shift;
	my $c_id       = shift;
	my $time     = shift;
	unless ($time) { $time = time; }
	my ($sec, $min, $hour, $mday, $mon, $year) = localtime($time);
	$year += 1900; $mon += 1;
	$diary->{dbh}->do("UPDATE $diary->{entry_table} SET title = '$title', contents = '$contents', c_id=$c_id, year=$year, month=$mon, day=$mday, timestamp=$time WHERE id = $id");
}


##############################################
# getEntry
##############################################

sub getEntry {
	my $diary = shift;
	my $id   = $diary->escape(shift, 'int');
	my @ret = $diary->getall("SELECT * FROM $diary->{entry_table} WHERE id = $id");
	return $ret[0];
}


##############################################
# sendTrackbackPing
##############################################

sub sendTrackbackPing {
    use utf8;
    my ($diary, $url, $title, $contents, $id) = @_;
    $id = $diary->getColumn("SELECT MAX(id) FROM $diary->{entry_table}") unless ($id);
    $contents =~ s/<image="([A-Za-z0-9\-\_]*\.(jpg|png|gif|bmp|jpeg))">//ig;
    my %form = (
	title => $title, 
	excerpt => substr($diary->br2n($contents),0,50),
	url => $diary->{afap}->get_site_info('web_root')."/apps/$diary->{afap}->{install_name}/index.cgi?id=$id",
	blog_name => $diary->{afap}->get_app_info("install_title")."/".$diary->{afap}->get_owner_info('nickname'),
	);
    my $req = POST($url, [%form]);
    my $ua = new LWP::UserAgent;
    my $res = $ua->request($req);
    my $str = $res->as_string;
    if ($str =~ /<error>[^1]*1[^<]*<\/error>/) {
	$diary->errorExit('Failed to send trackback ping');
    }
}

##############################################
# removeUploadedImage
##############################################

    sub removeUploadedImage {
	my ($diary, $id) = @_;
    
	$id = $diary->getColumn("SELECT MAX(id) FROM $diary->{entry_table}") unless ($id);
	
	my $imgdir = "$diary->{datadir}img/$id/";
	my $thumbdir = "$diary->{datadir}img/$id/thumb/";
	local (*DIR);
	if (-d $thumbdir) {
		opendir(DIR, $thumbdir);
		while (my $file = readdir(DIR)) {
			unlink ($thumbdir.$file) if (-f $thumbdir.$file);
		}
		closedir(DIR);
		rmdir $thumbdir;
	}
	if (-d $imgdir) {
		opendir(DIR, $imgdir);
		while (my $file = readdir(DIR)) {
			unlink ($imgdir.$file) if (-f $imgdir.$file);
		}
		closedir(DIR);
		rmdir $imgdir;
	}
    }

##############################################
# copyUploadImage
##############################################
sub copyUploadImage {
    my ($diary, $id) = @_;
    my $imgdir = "$diary->{datadir}img/$id/";
    my $thumbdir = "$diary->{datadir}img/$id/thumb/";
    my $tmp_imgdir = "$diary->{datadir}tmp/";
    my $tmp_thumbdir = "$diary->{datadir}tmp/thumb/";
    my $file;
    local (*DIR);
    unless (-d $imgdir) {
	mkdir $imgdir;
    }
    unless (-d $thumbdir) {
	mkdir $thumbdir;
    }

    if (-d $tmp_thumbdir) {
	opendir(DIR, $tmp_thumbdir);
		while ($file = readdir(DIR)) {
		    move($tmp_thumbdir.$file, $thumbdir.$file);
		}
	closedir(DIR);
    }
    if (-d $tmp_imgdir) {
	opendir(DIR, $tmp_imgdir);
		while ($file = readdir(DIR)) {
		    move($tmp_imgdir.$file, $imgdir.$file);
		}
	closedir(DIR);
    }
}


sub removeFiles {
    my ($diary, $rmdir) = @_;
    
    local (*DIR);
    my $file;
    if (-d $rmdir) {
	opendir(DIR, $rmdir);
	while ($file = readdir(DIR)) {
	    unlink ($rmdir.$file) if (-f $rmdir.$file);
	}
	closedir(DIR);
    }

}

sub copyFiles {
    my ($diary, $id) = @_;
    my $tmp_imgdir = "$diary->{datadir}tmp/";
    my $tmp_thumbdir = "$diary->{datadir}tmp/thumb/";
    my $imgdir = "$diary->{datadir}img/$id/";
    my $thumbdir = "$diary->{datadir}img/$id/thumb/";
    local (*DIR);
    my $file;
    if (-d $thumbdir) {
	opendir(DIR, $thumbdir);
	while ($file = readdir(DIR)) {
	    copy ($thumbdir.$file, $tmp_thumbdir.$file);
	}
	closedir(DIR);
    }
    if (-d $imgdir) {
	opendir(DIR, $imgdir);
	while ($file = readdir(DIR)) {
	    copy ($imgdir.$file, $tmp_imgdir.$file);
	}
	closedir(DIR);
    }
}

}
1;
