#     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 checking the definitions
# author: Bostjan Spetic, igzebedze@cyberpipe.org
# 19.12.2004

use strict;

sub do_internal_test {
	my (undef,$silent) = @_;	# silent mode for checking without window...
	my $form = &get_form;
	my $ok = 1; 
	my %count_teacher_lessons; 
	my %count_class_lessons; 
	
	my $lessons = $form->get_widget('entry_periods')->get_text;
	my $days = $form->get_widget('entry_days')->get_text;
	my $total = $lessons * $days;

# build the dialog	
	my $dialog = new Gtk2::Dialog(gettext('Testing definitions...'),
											$form->get_widget('window_main'),
											'destroy_with_parent',
											'gtk-close' => 'close');
	my $layout = new Gtk2::ScrolledWindow();
	my $text = new Gtk2::TextView();
	my $notice = new Gtk2::TextBuffer(); 
		$text->set_editable(0);
		$text->set_buffer($notice);		
	$layout->add($text);
	$dialog->vbox->add ($layout);
 	my $progress;
	if (!$silent) { 
		$progress = new Gtk2::ProgressBar(); 
		$dialog->vbox->add($progress);
	} else { 
		$progress = $form->get_widget('progressbar_main'); 
		$progress->set('visible' => 1);
	}
		$dialog->vbox->set_child_packing($progress, 0,0,0,'end');
		$dialog->set_keep_above(1);
		$dialog->set_default_size(450,250);
		$dialog->signal_connect (response => sub { $_[0]->destroy });
	if (!$silent) { $dialog->show_all; }
	#$dialog->show_all;

# tablix2_test usage...
#	my $tablix = &get_tablix;
#	if ($tablix eq 'tablix2') {
#		return &tablix2_test($notice);
#	} 

# or our own test...
 	my $e = gettext("Doing tests:	
	- for all required tuple definitions (teacher-subject)
	- if all required capability places are set up
	- if all required preferred-rooms are set up
	- if all required classes were defined
Note: These tests are just a quick look around.
They will not find all possible problem Tablix will look for.").
				"\n--------------------------------------------------------\n";
 	$notice->insert($notice->get_end_iter,$e);								 	
	
	my $tv_tt = $form->get_widget('treeview_tt')->get_model;
	my $no = $tv_tt->iter_n_children(undef);
	$tv_tt->foreach(sub {
		my (undef,undef,$child_iter) = @_; 		
		my ($id,$subject,$teacher,$perweek,$room,$period,$day,$tt_restss) = $tv_tt->get($child_iter,0,1,2,3,4,5,6,7);

# count lessons	
	if ($teacher and $subject) {
		if (!$perweek) {
			if ((defined $room) and (defined $period) and (defined $day)) {
				my $lessns = 1; 
	 			if (!defined $count_teacher_lessons{$teacher}) { 
					$count_teacher_lessons{$teacher} = $lessns; 
	 			} else {	
					$count_teacher_lessons{$teacher} = $count_teacher_lessons{$teacher} + $lessns;
				}		
	 			if (!defined $count_class_lessons{$id}) { 
					$count_class_lessons{$id} = $lessns; 
	 			} else {	
					$count_class_lessons{$id} = $count_class_lessons{$id} + $lessns;
				}
# check tt: if the lessons setting are correct (perweek or room/period/day)
			} else {
 	 	 	 	my $error = gettext("error: ").gettext("Class")." $id, ".
								gettext("for tuple")." $subject - $teacher ".
								gettext("is not properly scheduled.\n");
 	 	 	 	$notice->insert($notice->get_end_iter,$error);						
			}
		} else {
	 			if (!defined $count_teacher_lessons{$teacher}) { 
					$count_teacher_lessons{$teacher} = $perweek; 
	 			} else {	
					$count_teacher_lessons{$teacher} = $count_teacher_lessons{$teacher} + $perweek;
				}		
	 			if (!defined $count_class_lessons{$id}) { 
					$count_class_lessons{$id} = $perweek; 
	 			} else {	
					$count_class_lessons{$id} = $count_class_lessons{$id} + $perweek;
				}		
		}
	}
		
		if ($id and $subject) {
# check tt: if teacher-subject pairs are defined in teachers		
		if (&check_teacher_subject($teacher,$subject,0,$form,$notice) == 0) { $ok = 0; }
# check tt_rests:
		if ($tt_restss) {
	 	 		foreach my $sub (split/;/,$tt_restss) {  
	 	 			my @rests = split/:/,$sub;
	 	 			my $rest_type = $rests[0];
	 	 			if (($rests[1])) {			# for each restriction check $rest_type and $rest_val	 	 	 															
						my $mod_active = &check_module($rest_type);
						if (!$mod_active) { 
							$ok = 0; 
							my $error = gettext("Module for restriction").' '.$rest_type.' '.gettext("is not active.\n"); 
							$notice->insert($notice->get_end_iter,$error);	
						} 
	 	 				foreach my $rest_val (split/\,/,$rests[1]) {	
	 			# if we want more of the same teacher... :)		
							if ($rest_type eq "teacher-also") {
								if ($rest_val eq $teacher) {
	 								$ok = 0;
	 	 	 	 	 	 	 	 	my $error = gettext("error: ")."\'$rest_type\' - \'$rest_val\' ".
													gettext("for")." \'$teacher\' ".
													gettext("is irrational!.\n");
	 	 	 	 	 	 	 	 	$notice->insert($notice->get_end_iter,$error);		
								}
				# add his lessons to full count
								if (!defined $count_teacher_lessons{$teacher}) { $count_teacher_lessons{$teacher} = $perweek; 
								} else {	$count_teacher_lessons{$teacher} = $count_teacher_lessons{$teacher} + $perweek;}
							} 
				# more tests ?
	 	 	 			}
	 	 	 		}
				}
		}
# check if the class exists...
		if (&find_clist_row('classs',$id) eq "new") { 
			$ok = 0;
 	 	 	my $error = gettext("error: ").gettext("Class")." \'$id\' ".gettext("is not defined.\n");
 	 	 	$notice->insert($notice->get_end_iter,$error);								
		}	
# nextstep		
		$progress->pulse;
		#$progress->set_fraction($counter2 * (1 / $no)); 
		Gtk2->main_iteration;
		}
	});
	my $error;
	if ($ok == 1) { 
		$error = gettext("check: ok\n"); 
	} else { 
		$error = gettext("check: errors found\n"); 
	}
	$notice->insert($notice->get_end_iter,$error);

	$silent = $ok;
# ------------------------------------------------------------
	$ok = 1;
	$error = "\n-----------------------\n".gettext("Stats report:\n").
				gettext("Checking for teachers and classes that were scheduled\nmore lessons than there are in a week.\n");
	$notice->insert($notice->get_end_iter,$error);
	while ((my $key, my $val) = each (%count_teacher_lessons)) {
		if ($val > $total) { 
			$error = gettext("stats: ").gettext("Teacher")." $key ".
						gettext("is scheduled for")." $val ".
						gettext("lessons,\n\twhen there are only")." $total ".
						gettext("in a week.\n");
		 	$notice->insert($notice->get_end_iter,$error);
			$ok = 0;
		}
	}
	while ((my $key, my $val) = each (%count_class_lessons)) {
		if ($val > $total) { 
			$error = gettext("stats: ").gettext("Class")." $key ".
						gettext("is scheduled for")." $val ".
						gettext("lessons,\n\twhen there are only")." $total ".
						gettext("in a week.\n");
			$notice->insert($notice->get_end_iter,$error);
			$ok = 0;
		}
	}
	if ($ok == 1) { $error = gettext("check: ok\n"); } else { $error = gettext("check: errors found\n"); }	
	$notice->insert($notice->get_end_iter,$error);

	if ($silent) { $silent = $ok; }
	if (!$silent) { $dialog->show_all; }
	$progress->set('visible' => 0);
	return $silent;
}
# -----------------------------------------------------------------
sub check_teacher_subject {
	my ($teacher,$subject,$ok,$form,$notice) = @_;
		my $tw = $form->get_widget('treeview_teachers')->get_model;	 	
		$tw->foreach(sub {	# will stop when it find first teacher-subject with satisfied place restrictions
	 	 	my (undef,undef,$child_iter) = @_; 	 	 		
	 	 	my ($t,$s,$r) = $tw->get($child_iter,0,1,2);	 		
			if ($t and $s) {
			if (($t eq $teacher) and ($s eq $subject)) { 	# if found but need special room, check for it 		
	 	 		if ($r) { foreach my $sub (split/;/,$r) {  
	 	 			my @rests = split/:/,$sub;
	 	 			my $rest_type = $rests[0];
	 	 			if (($rests[1])) {			# for each restriction check $rest_type and $rest_val	 	 	 															
						my $mod_active = &check_module($rest_type);
						if (!$mod_active) { 
							$ok = 0; 
							my $error = gettext("Module for restriction")." '$rest_type' ".
										gettext("is not active.\n"); 
							$notice->insert($notice->get_end_iter,$error);	
						} 
	 	 				foreach my $rest_val (split/\,/,$rests[1]) {	
	 						if ($rest_type eq ("capability-place" or "preferred-room")) {
								$ok = &check_building_rests($rest_type,$rest_val,$form); 
								if ($ok == 1) { return 1; } else {
		 	 	 	 	 	 	 	my $error = gettext("error: ").
													gettext("couldnt find:")." \'$rest_type\' - \'$rest_val\' ".
													gettext("for")." \'$teacher\'-\'$subject\'.\n";
	 		 	 	 	 	 	 	$notice->insert($notice->get_end_iter,$error);								
								}
							}
	 	 	 			}
	 	 	 		}
	 	 	 	} } else { $ok = 1; return 1; } 					
			}
			} 
			return 0; 
	 	} );
	if ($ok == 0) { 
		my $error = gettext("error: ")."\'$teacher\'-\'$subject\' ".
						gettext("pair does not exist, or there is a problem with room restrictions.\n\n");
		$notice->insert($notice->get_end_iter,$error);
	}
	return $ok;
}
sub check_building_rests {
	my ($rest_type,$rest_val,$form) = @_;	
	my $tv_b = $form->get_widget('treeview_classrooms')->get_model;
	my $ok = 0; 
	$tv_b->foreach(sub {
		my (undef,undef,$child_iter) = @_; 	 
		my ($b,$b_rests) = $tv_b->get($child_iter,0,1);
	# check if special type exists
		if (($rest_type eq "capability-place") and $b_rests) {	
 	 		foreach my $subb (split/;/,$b_rests) {  
 	 			my @restsb = split/:/,$subb;
 	 			my $rest_typeb = $restsb[0];
 	 			if ($restsb[1]) {
 	 				foreach my $rest_valb (split/\,/,$restsb[1]) {	
						if (($rest_type eq $rest_typeb) and ($rest_val eq $rest_valb)) { $ok = 1; return 1; }
 	 				}
 	 			}
 	 		}
	# check if preferred room exists
		} elsif ($rest_type eq "preferred-room") { 
			if ($b eq $rest_val) { $ok = 1; return 1; }
		} 
	}); 
	return $ok;	
}

sub tablix2_test {
	my ($notice) = @_;
	
	my $state = 1;
	my $form = &get_form;
	my $tempdir = &get_temp;
	my $filename = "$tempdir/temp.xml";
	my $tablix = $form->get_widget('entry_tablix_params')->get_text;

	&save_file($filename,2,1);	# WARN: doesn't save the project...
	my $test = readpipe("tablix2_test --file \"\" $filename");
	
	
	
	return $state;
}

 return 1;
