# Copyright (C) 2005 FishGrove 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 Album;

use strict;
use DBI;
use Jcode;
use HTML::Template;
use Config::Tiny;
use Album::L10N;

##############################################
# Constructor 
##############################################
sub new {
	my ($proto, $afap) = @_;
	unless ($afap) { die("Album::new: Error: missing username\n"); }

	my $self = {};
	$self->{afap}  = $afap;
	$self->{tmpfile}= $afap->get_userdata_dir()."/.sqltmp";
	$self->{album_tb}= "album_$afap->{install_name}_entries";
	$self->{image_tb}= "album_$afap->{install_name}_images";
	$self->{comment_tb}= "album_$afap->{install_name}_comments";
	$self->{dbh} = undef;
	#initialize

	###########################
	#Locale init
	###########################
	$self->{lh} = Album::L10N->get_handle(($afap->get_site_info("locale"),
                                               $afap->get_site_info("locale")));
	###########################
	
	unless(-f $self->{tmpfile}) {
	    open(TMP,"> $self->{tmpfile}");
	    close(TMP); 	    
	    $self->{dbh} = $afap->get_userdata_dbh();
	    #Album table
	    my $query;
	    $query="id INTEGER".get_query_primarykey($self)."
			title		TEXT,
			contents	TEXT,
			timestamp	INTEGER,
			update_time	INTEGER,
			user		TEXT,
			afid		TEXT,
			pswd		TEXT,
			ord		INTEGER";
			
	    $self->{dbh}->do("CREATE TABLE $self->{album_tb} ($query)");

	    #Comment table
	    $query="pkey INTEGER".get_query_primarykey($self)."
			id		INTEGER,
			user		TEXT,
			afid		TEXT,
			comment		TEXT,
			pswd		TEXT,
			timestamp	INTEGER";
		
	    $self->{dbh}->do("CREATE TABLE $self->{comment_tb} ($query)");



	    # Image table 
	    $query="pkey INTEGER".get_query_primarykey($self)."
			id		INTEGER,
			image		TEXT,
			title		TEXT,
			user		TEXT,
			afid		TEXT,
			comment		TEXT,
			pswd		TEXT,
			timestamp	INTEGER";

	    $self->{dbh}->do("CREATE TABLE $self->{image_tb} ($query)");

	}
	else {
	    $self->{dbh} = $afap->get_userdata_dbh();
        }

	bless $self, $proto;
	return $self;
}

##############################################
# destructor
##############################################

sub DESTROY {
	my $self = shift;
	$self->{dbh}->disconnect;
}


##############################################
# addAlbum
##############################################

sub addAlbum {
	my ($self, $title, $contents, $user, $afid, $time) = @_;
	unless ($time) { $time = time; }

  	my $id = $self->getColumn("SELECT MAX(id) FROM $self->{album_tb}");
	$title = $self->escape($title);
	$user = $self->escape($user);
	$contents = $self->escape($contents);

	$self->{dbh}->do("INSERT INTO $self->{album_tb} (title, contents, timestamp, update_time, user, afid, pswd, ord) VALUES ('$title', '$contents', $time, $time, '$user', '$afid', '', '')");

  	$id = $self->getColumn("SELECT MAX(id) FROM $self->{album_tb}");

        my $data_dir=$self->{afap}->get_userdata_dir()."/";
  	$data_dir.= $id;
      	if (!-d $data_dir){
        	mkdir $data_dir, 0777;
        }
  	$data_dir.= "/thumbnail";
      	if (!-d $data_dir){
	  	mkdir $data_dir, 0777;
        }

	$self->{afap}->post_news($title, "", $user,
				 $self->{afap}->get_site_info("web_root") . "/apps/". 
				 $self->{afap}->{install_name} . "/album.cgi?id=".$id);
}

##############################################
# addImage
##############################################

sub addImage {
	my ($self, $id, $title, $user, $afid, $comment, $image) = @_;
	my $time = time;

	$title = $self->escape($title);
	$comment = $self->escape($comment);
	$image = $self->escape($image);
	$user = $self->escape($user);

	my @same = $self->getall("SELECT id FROM $self->{image_tb} WHERE id = $id AND image = '$image'");
	if($#same > 0) {
	$self->{dbh}->do("UPDATE $self->{image_tb} SET title = '$title', comment='$comment', user='$user', afid='$afid', time=$time WHERE id = $id AND image='$image'");
        }else{
	$self->{dbh}->do("INSERT INTO $self->{image_tb} (id, image, title, user, afid, comment, pswd, timestamp) VALUES ($id, '$image', '$title', '$user', '$afid', '$comment', '', $time)");
      	}
}



##############################################
# updateEntry
##############################################

sub updateEntry {
	my ($self, $id, $title, $contents) = @_;
	$title = $self->escape($title);
	$contents = $self->escape($contents);
  	my $time = time;
	$self->{dbh}->do("UPDATE $self->{album_tb} SET title = '$title', contents = '$contents', update_time=$time WHERE id = $id");
}

##############################################
# updateImage
##############################################

sub updateImage {
	my ($self, $id, $title, $comment, $image) = @_;
	$title = $self->escape($title);
	$comment = $self->escape($comment);
	$image = $self->escape($image);
  	my $time = time;
	$self->{dbh}->do("UPDATE $self->{image_tb} SET title = '$title', comment = '$comment' WHERE id = $id AND image='$image'");
}

##############################################
# updateTimestamp
##############################################

sub updateTimestamp {
	my ($self, $id) = @_;
  	my $time = time;
	$self->{dbh}->do("UPDATE $self->{album_tb} SET update_time=$time WHERE id = $id");
}


##############################################
# removeAlbum
##############################################

sub removeAlbum {
	my ($self, $id) = @_;
        my @ret = $self->getall("SELECT * FROM $self->{image_tb} WHERE id = $id");
	$self->{dbh}->do("DELETE FROM $self->{album_tb} WHERE id = $id");
	$self->{dbh}->do("DELETE FROM $self->{comment_tb} WHERE id = $id");
	$self->{dbh}->do("DELETE FROM $self->{image_tb} WHERE id = $id");
        my $data_dir=$self->{afap}->get_userdata_dir()."/".$id."/";
       	my $thumb_dir=$data_dir."thumbnail/";
  	foreach(@ret){
    		unlink($thumb_dir.$_->{image});
    		unlink($data_dir.$_->{image});
        }
	if (-d $thumb_dir){
      		rmdir $thumb_dir;
      	}
	if (-d $data_dir){
     		rmdir $data_dir;
      	}
}

##############################################
# removeImage
##############################################

sub removeImage {
	my ($self, $id, @pkey) = @_;
        my $data_dir=$self->{afap}->get_userdata_dir()."/".$id."/";
       	my $thumb_dir=$data_dir."thumbnail/";
  	my @ret;
  	foreach(@pkey){
		@ret = $self->getall("SELECT * FROM $self->{image_tb} WHERE id = $id AND pkey=$_");
		$self->{dbh}->do("DELETE FROM $self->{image_tb} WHERE id = $id AND pkey=$_");
          	
  		unlink($data_dir.$ret[0]->{image});
	  	unlink($thumb_dir.$ret[0]->{image});
  	}
}

##############################################
# removeComment
##############################################

sub removeComment {
	my ($self, $id, @pkey) = @_;
  	foreach(@pkey){
		$self->{dbh}->do("DELETE FROM $self->{comment_tb} WHERE id = $id AND pkey=$_");
      	}
}


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

sub getEntry {
	my ($self, $id) = @_;
	my @ret = $self->getall("SELECT * FROM $self->{album_tb} WHERE id = $id");
	return $ret[0];
}

##############################################
# getImage
##############################################

sub getImage {
	my ($self, $id, $pkey) = @_;
	my @ret = $self->getall("SELECT * FROM $self->{image_tb} WHERE id = $id AND pkey=$pkey");
	return $ret[0];
}
sub getAllImage {
	my ($self, $id) = @_;
	return $self->getall("SELECT * FROM $self->{image_tb} WHERE id = $id");
}

sub checkImagefile {
	my ($self, $id, $image) = @_;
	$image = escape($image);
	my @ret = $self->getall("SELECT * FROM $self->{image_tb} WHERE id = $id AND image='$image'");
	return $ret[0];
}

##############################################
# getNewestEntries
##############################################

sub getNewestEntries {
	my ($self, $num) = @_;
	unless ($num) { $num = 5; }
	return $self->getall("SELECT * FROM $self->{album_tb} ORDER BY update_time DESC LIMIT $num");
}

##############################################
# getNewestAlbumId
##############################################

sub getNewestAlbumId {
  	my ($self) = @_;
  	my @ret = $self->getall("SELECT MAX(id) as id FROM $self->{album_tb}");
  	return $ret[0];
}

##############################################
# getAllEntries
##############################################

sub getAllEntries {
	my ($self) = @_;
	return $self->getall("SELECT * FROM $self->{album_tb} ORDER BY update_time DESC");
}


##############################################
# addComment
##############################################

sub addComment {
	my ($self, $id, $user, $afid, $comment) = @_;
	my $time = time;
	$user = $self->escape($user);
	$comment = $self->escape($comment);
	
	#
	my @same = $self->getall("SELECT id FROM $self->{comment_tb} WHERE user = '$user' AND comment = '$comment'");
	if($#same >= 0) { return; }
	
	$self->{dbh}->do("INSERT INTO $self->{comment_tb} (id, user, afid, comment, pswd, timestamp) VALUES ($id, '$user', '$afid', '$comment', '', $time)");
}


##############################################
# getComments
##############################################
sub getComments {
	my ($self, $id) = @_;
	return $self->getall("SELECT * FROM $self->{comment_tb} WHERE id = $id ORDER BY timestamp");
}

##############################################
# getCommentsNo
##############################################
sub getCommentsNo {
	my ($self, $id) = @_;
	return $self->getColumn("SELECT COUNT(*) FROM $self->{comment_tb} WHERE id = $id");
}

##############################################
# getColumn
##############################################
sub getColumn {
	my ($self, $query) = @_;
	my $sth = $self->{dbh}->prepare($query);
	$sth->execute;
	my $num;
	$sth->bind_columns(undef, \$num);
	$sth->fetch;
	$sth->finish;
	if($num) {
		return $num;
	}
	else {
		return 0;
	}
}

##############################################
# get all columns
##############################################
sub getall {
	my ($self, $query) = @_;

	my $sth = $self->{dbh}->prepare($query);
	$sth->execute;

	my @ret;
	while(my $row = $sth->fetchrow_hashref) {
		push @ret, $row;
	}
	$sth->finish;

	return @ret;
}

##############################################
# escape
##############################################
sub escape {
	my ($self, $str) = @_;

        $str =~ s/[\t\a]//g;
        $str =~ s/&/&amp;/g;
	$str =~ s/'/&quot;/g;
	$str =~ s/"/&quot;/g;
	$str =~ s/</&lt;/g;
	$str =~ s/>/&gt;/g;
	$str =~ s/\r\n/<br \/>/g;
	$str =~ s/[\r\n]/<br \/>/g;
	$str =~ s/(s?https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)/<a href="$1">$1<\/a>/g;
	$str = $self->{dbh}->quote($str);
	return $str;
}


############################################################################
# get primary key for DBs
############################################################################
sub get_query_primarykey {
    my ($self) = @_;
    my $DBConfig = Config::Tiny->new();
    $DBConfig = Config::Tiny->read("$self->{afap}->{af}->{site__user_dir}/db.cfg");
    my $db_type = $DBConfig->{db}->{type};
    my $query;

    if ($db_type eq "sqlite"){
	$query = " PRIMARY KEY,";
    }elsif ($db_type eq "mysql"){
	$query = " AUTO_INCREMENT PRIMARY KEY,";
    }
    return $query;
}


############################################################################
#L10N added by slash
############################################################################
sub translate_templateL10N{
    my $af=shift;
    my $mesg = shift;
    
    my $tag_body ="";
    my $text_value="";
    my $param_value="";
    
    while( $mesg =~ /<AF_M ([^>]+)>/ ){
	$tag_body = $1;
	
	$tag_body =~ /text(\s*)=(\s*)["']([^"']*)["'](\s*)param(\s*)=(\s*)["']([^"']*)["']/;
	$text_value=$3;
	$param_value=$7;
	if($text_value eq ""){
	    $tag_body =~ /text(\s*)=(\s*)["']([^"']*)["']/;
	    $text_value=$3;
	}
	
	my $sbst = $af->{lh}->maketext($text_value, $param_value);
	
#	debug_print("Album::translate tag_body = [$tag_body]\n");
#	debug_print("Album::translate \t text=[$text_value]\n");
#	debug_print("Album::translate \t param=[$param_value]\n");
#	debug_print("Album::translate \t sbst=[$sbst]\n");
	
	$mesg =~ s/\Q<AF_M $tag_body>\E/$sbst/g;
    }
    return($mesg);
}

############################################################################
#Show Error
############################################################################
sub errorExit {
    my ($self,$msg) = @_;
    my $affelio_id = $self->{afap}->get_visitor_info("afid");
    my $visitor_type=$self->{afap}->get_visitor_info("type");
    
    if($visitor_type eq ""){
	$visitor_type="pb";
    }
    my $tmpl = HTML::Template->new(filename => "./templates/error.tmpl");
    $tmpl->param(V_TYPE => $visitor_type);
    $tmpl->param(AF_ID => $affelio_id);
    $tmpl->param(MSG => $msg);

    print $self->translate_templateL10N( $tmpl->output );
    print $self->{afap}->get_HTML_footer();
    exit;
}

##############################################
# escape
##############################################
sub escape {
    my ($self, $str, $type) = @_;
    
    if ($type eq 'int') {
	return int($str);
    }
    else {
	$str =~ s/[\t\a]//g;
	$str =~ s/&/&amp;/g;
	$str =~ s/["']/&quot;/g;
	$str =~ s/</&lt;/g;
	$str =~ s/>/&gt;/g;
	$str =~ s/&lt;(\/?)(a|p|i|b|big|strong|small|em|u|blockquote)&gt;/<$1$2>/ig;
	$str =~ s/&lt;a +href=(&quot;)?(s?https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+) *(&quo\
t;)? *&gt;/<a href="$2">/ig;
	$str =~ s/&quot;"/"/g;
	$str =~ s/(\r\n|\r|\n)/<br \/>/g;
	
	while ($str =~ /(<(a|p|i|b|big|strong|small|em|u|blockquote)\b(?:(?!<\/\2>).)*(?:<\2>|$))\
/sigx) {
	    $self->errorExit("Error: You may mistype a tag or forget to close it.");
	}
    }
    
    return $str;
}

sub escape_all {
    my ($self, $str) = @_;
    
    $str =~ s/[\t\a]//g;
    $str =~ s/&/&amp;/g;
    $str =~ s/['"]/&quot;/g;
    $str =~ s/</&lt;/g;
    $str =~ s/>/&gt;/g;
    $str =~ s/(\r\n|\r|\n)/<br \/>/g;
    
    return $str;
}

1;



