#     G-Tablix, graphical user interface for Tablix
#     Copyright (C) 2004,2005 Bostjan Spetic
# 
#     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
#
# module for importing and exporting everything to Tablix XML
# author: Bostjan Spetic, igzebedze@cyberpipe.org
# contributions: Tomaz Solc
# 19.12.2004

use strict;

# --------- I / O --------------------------------
sub xml_result {
	my ($filename,$uid_entries,$defined_entries) = @_;
	my $form = &get_form;

# we get this filename directly from tablix, so we won't check anything!
	my $progress = $form->get_widget('progressbar_main');
	my $parser = XML::LibXML->new();

	my $file_opened = $parser->parse_file($filename); # build the XML
	$progress->set('visible' => 1);

 	my $root = $file_opened->getDocumentElement;
 	my @segs = $root->getChildNodes; 
	my $grade; my $days; my $periods;
	if ($root->nodeName eq "school") {	# tablix 0.1 file		 
 	 	foreach my $seg (@segs) {
			if ($seg->nodeName eq "parameters") { 
				($days,$periods) = &params_result($seg,$form); 
				$progress->pulse; Gtk2->main_iteration;
			} elsif ($seg->nodeName eq "timetable") { 
				&timetable_result($seg,$form,$defined_entries,$uid_entries); 
				$progress->pulse;  Gtk2->main_iteration; 
	 		} elsif ($seg->nodeName eq "chromo") { 
				$grade = &chromo_result($seg,$form,$defined_entries,$uid_entries); 
				$progress->pulse; Gtk2->main_iteration; 
	 		}
		}				
	} elsif ($root->nodeName eq 'ttm') {
	 	my $version = getNamedItem($root,"version"); 				
		my $grade = getNamedItem($root,"fitness"); 
		if (!defined $grade) { 
			&check(gettext("This file does not contain results from previous run:")."\n$filename\n".
				 	gettext("You can only open it as project."),'error',1);
		} else {
	 		foreach my $seg (@segs) {
				if ($seg->nodeName eq "events") { 
	 				&t2events($seg,$form,1,$defined_entries,$uid_entries); 
	 	 	 	} elsif ($seg->nodeName eq "resources") { 
	 	 	 		foreach my $type ($seg->getChildNodes) {
	 					if ($type->getFirstChild) {
	 						if ($type->nodeName eq 'constant') {
	 							($days,$periods) = &t2days($type,$form,1);
	 						} 
	 					}
	 				}
	 			}
	 		}
		}
	}
	$progress->set('visible' => 0);
	return ($uid_entries,$defined_entries,$grade,$days,$periods);
}
# ---------------------------------------------------------------------------

sub parse_xml {
	my ($filename,$form,$defined_tt_entries,$uid_tt_entries) = @_;

#TODO: lovi parserjeva sporocila...									
# nalozimo datoteko in vse potrebne veje
	
	my $progress = $form->get_widget('progressbar_main');

print "Opening $filename\n" if &get_debug;

  if (!-r $filename) {
  		print gettext("Error:")." $filename ".gettext("not readable").".\n";
		&check(gettext("Couldn't open file)")."\n$filename\n".
				 gettext("Check full path and permissions"),'error',1); 
  } else {
print "Preparing parser\n" if &get_debug;
	   if (!-w $filename) { &check(gettext("File")." \n$filename\n".
				 gettext("is not writable. Changes will not be saved."),'error',1); }
	 	my $parser = XML::LibXML->new();
		$parser->expand_entities(0);	# skip loading internet dtds
	 	my $file_opened;
	 	my $file_type = &get_file_type($filename);

	 	if ($file_type eq 'gzip') {
	 		my $content = readpipe("gunzip -c $filename");
	 		$file_opened = $parser->parse_string($content);
	 	} elsif ($file_type eq 'XML') {
	 		$file_opened = $parser->parse_file($filename); # build the XML
	 	} else {
	 		print gettext("Error: didn't recognize file type:")." $filename\n";
		}
	 	if (!$file_opened) {
	 		print gettext("Error: when parsing")." $filename\n";
	 		&check(gettext("Couldn't parse file")."\n$filename\n".
					 gettext("This Could be a syntax error"),'error',1);
	 	} else {
			$progress->set('visible' => 1);
	 # zapomnimo si encoding	
	 	  	my $encoding = $file_opened->encoding; 
	 	 	if (defined $encoding) { $form->get_widget('entry_encoding')->set_text($encoding); }

print "Detecting file type\n" if &get_debug;
	 	 	my $root = $file_opened->getDocumentElement;
	 	 	my @segs = $root->getChildNodes;
# tablix 0.1 file			 
		 	if ($root->nodeName eq "school") {	 
	 	 	 	foreach my $seg (@segs) {
	 	 	 		if ($seg->nodeName eq "info") { &infos($seg,$form); $progress->pulse; Gtk2->main_iteration; 
	 	 	 		} elsif ($seg->nodeName eq "parameters") { &params($seg,$form); $progress->pulse; Gtk2->main_iteration;
	 	 	 		} elsif ($seg->nodeName eq "subjects") { &subjects($seg,$form); $progress->pulse; Gtk2->main_iteration; 
	 	 	 		} elsif ($seg->nodeName eq "building") {	&building($seg,$form); $progress->pulse; Gtk2->main_iteration; 
	 	 	 		} elsif ($seg->nodeName eq "timetable") { &timetable($seg,$form,$defined_tt_entries,$uid_tt_entries); $progress->pulse;  Gtk2->main_iteration; 
	 	 	 		} elsif ($seg->nodeName eq "chromo") { &chromo($seg,$form,$defined_tt_entries,$uid_tt_entries); $progress->pulse; Gtk2->main_iteration; 
	 	 	 		}
				}	
				&load_result($filename);     			
# tablix > 2 file
			} elsif ($root->nodeName eq 'ttm') {	
	 	 	 	my $version = getNamedItem($root,"version"); 				
				my $fitnes = getNamedItem($root,"fitness"); 
				if ($fitnes ne "") { 
					&check(gettext("This file contains results from previous run:")."\n$filename\n".
						 	gettext("You can only import it to results view."),'error',1);
				} else {
print "start parsing tablix2\n" if &get_debug;
	 				foreach my $seg (@segs) {
&debug ("parse ".$seg->nodeName."\n");
	 	 	 	 		if ($seg->nodeName eq "info") {
							&infos($seg,$form); $progress->pulse; Gtk2->main_iteration; 
	 	 	 	 		} elsif ($seg->nodeName eq "modules") { 
							&params($seg,$form); $progress->pulse; Gtk2->main_iteration; 
	 	 	 	 		} elsif ($seg->nodeName eq "resources") { 
	 	 	 	 			foreach my $type ($seg->getChildNodes) {
	 							if ($type->getFirstChild) {
&debug ("parse ".$type->nodeName."s\n");								
	 								if ($type->nodeName eq 'constant') {
	 									&t2constants($type,$form); $progress->pulse; Gtk2->main_iteration;
	 								} elsif ($type->nodeName eq 'variable') {
	 									&t2variables($type,$form); $progress->pulse; Gtk2->main_iteration;
	 								}
	 							}
	 						}
	 					} elsif ($seg->nodeName eq "events") { 
	 						&t2events($seg,$form); 
	 						$progress->pulse; 
	 						Gtk2->main_iteration; 
	 	 	 	 		}
	 				}
				}		
# fet file
			} elsif ($root->nodeName =~ /^FET/) {	
	 	 	 	foreach my $seg (@segs) {
	 	 	 		if ($seg->nodeName eq "Hours_List") { &fet_hours($seg,$form); $progress->pulse; Gtk2->main_iteration;
	 	 	 		} elsif ($seg->nodeName eq "Days_List") { &fet_days($seg,$form); $progress->pulse; Gtk2->main_iteration; 
	 	 	 		} elsif ($seg->nodeName eq "Students_List") { &fet_students($seg,$form); $progress->pulse; Gtk2->main_iteration; 
	 	 	 		} elsif ($seg->nodeName eq "Teachers_List") { &fet_teachers($seg,$form); $progress->pulse;  Gtk2->main_iteration;
	 	 	 		} elsif ($seg->nodeName eq "Subjects_List") { &fet_subjects($seg,$form); $progress->pulse;  Gtk2->main_iteration; 
					} elsif ($seg->nodeName eq "Activities_List") { &fet_activities($seg,$form); $progress->pulse;  Gtk2->main_iteration; 
	 	 	 		} elsif ($seg->nodeName eq "Equipments_List") {	&fet_equipment($seg,$form); $progress->pulse; Gtk2->main_iteration; 
	 	 	 		} elsif ($seg->nodeName eq "Rooms_List") { &fet_rooms($seg,$form);  Gtk2->main_iteration; $progress->pulse; 
	 	 	 		} elsif ($seg->nodeName eq "Time_Constraints_List") { &fet_time_constraints($seg,$form); $progress->pulse;  Gtk2->main_iteration; 
	 	 	 		} elsif ($seg->nodeName eq "Space_Constraints_List") { &fet_time_constraints($seg,$form); $progress->pulse;  Gtk2->main_iteration; 
	 	 	 		}
				}								
			} else {	# error
				&check(gettext("Couldn't parse file")."\n$filename\n".
						 gettext("This is a syntax error in the root element."),'error',1);
				return 0;
			}			
			&combo_change("classs");
			&combo_change("classrooms");
			&combo_change("subjects");
			&combo_change("teachers");

	 	 	$form->get_widget('window_main')->set_title("Gtablix - $filename");
			&on_treeview_tt_unselect_all;
			$progress->set('visible' => 0);
			&write_to_statusbar(gettext("Loaded file")." $filename.");
	 	}
	}
}

sub generateXML { 	# generira XML (kdo bi si mislil... :)
	my ($filename,$form,$defined_tt_entries,$uid_tt_entries,$how) = @_;	# how: 1 / 2
	if ((!defined $how) or ($how eq "")) { $how = 1; }

	my $progress = $form->get_widget('progressbar_main');
	my $output; 
	my $time = localtime; 
	my $errors;
	my $encoding = 'utf-8';
#	my $encoding = $form->get_widget('entry_encoding')->get_text;
# heading
	$output = "<?xml version=\"1.0\" encoding=\"$encoding\"?>\n";
	$progress->set('visible' => 1);

	if ($how == 1) { 
		$output .= "<school>\n"; 
		$output .= "<!-- User XML data file for Tablix, created with Gtablix  -->\n";
		$output .= &XML_info($form);
		$output .= &XML_params("",$form,$how);
		$output .= &XML_subjects("",$form,$how);
		$output .= &XML_rooms("",$form,$how);
		$output .= &XML_tt("",$form,$defined_tt_entries,$uid_tt_entries,$how);
		$output .= &XML_chromo("",$form,$defined_tt_entries,$uid_tt_entries,$how);
		$output .= "</school>\n";
	} 
	elsif ($how == 2) { 
		$output .= '<!DOCTYPE ttm PUBLIC "-//Tablix//DTD TTM 0.2.0//EN"
						"http://www.tablix.org/releases/dtd/tablix2r0.dtd">';
		$output .= "<!-- User XML data file for Tablix2, created with Gtablix  -->\n";
		$output .= "<ttm version=\"0.2.0\">\n"; 
		$output .= &XML_info($form);
		$output .= &XML_params("",$form,$how);
		$output .= "\t<resources>\n\t\t<constant>\n";
		$output .= &XML2_teachers($form);
		$output .= &XML2_classs($form);
		$output .= "\t\t</constant>\n\t\t<variable>\n";
		$output .= &XML2_rooms($form);
		$output .= &XML2_time($form);
		$output .= "\n\t\t</variable>\n\t</resources>\n";
		$output .= &XML2_events($form);
		$output .= "</ttm>\n";
	}

# escape the < and >
	$output =~ s/(=".*)<(.*")/$1-$2/g;
	$output =~ s/(=".*)>(.*")/$1-$2/g;
	$output =~ s/(=".*)&(.*")/$1|$2/g;
	
# return to saving
	$progress->set('visible' => 0);
	return $output;
}

# ------ helpers -----------------------------------

sub XML_info {
	my ($form) = @_;
	my $output = "\t<info>\n".
		"\t\t<title>".$form->get_widget('entry_title')->get_text."</title>\n".
		"\t\t<address>".$form->get_widget('entry_notes')->get_text."</address>\n".
		"\t\t<author>".$form->get_widget('entry_author')->get_text."</author>\n".
		"\t</info>\n";
	return $output;
}

sub get_file_type {
	my ($what) = @_;
	my $type = readpipe("file $what"); chop($type);
	$type = (split/\:/,$type)[1];
	$type = (split/ /,$type)[1];
	return $type;
}

sub getNamedItem {
	my ($where,$what) = @_;
	foreach my $value ($where->attributes) {
		if ($value->name eq $what) {
			my $val = $value->value;
			return "$val";
		}
	}
	return "";
}

return 1;
