#     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
#
# author: Bostjan Spetic, igzebedze@cyberpipe.org
# module with special knowledge about tablix modules
# contributions: Tomaz Solc
# 5.3.2005

use strict;

my %widgets;

my %modules; 		# {'module_name.so'	 => 'basic-info' => { 'description' => 'description',
						#								 						 'filename' => 'filename' },
						# 								 'module-options' => [ opts... ],
						#								 #'restrictions' => [ rests... ]
						#								 'options' => { 'optioname' => { 
						#																	'required-resourcetypes' => [ type1, type2,... ],
						#																	'description' => 'description',
						#																	'name' => 'name'
						#																}
						#															}
						#								 'resource-restrictions' => { 'restname' => { 
						#																				 'required-resourcetypes' => [ type1, type2,... ],
						#																				 'description' => 'description',
						#																				 'name' => 'name'
						#																				}
						#															}
						#								 'tuple-restrictions' => { 'restname' => { 
						#																				 'required-resourcetypes' => [ type1, type2,... ],
						#																				 'description' => 'description',
						#																				 'name' => 'name'
						#																				}
						#															}
						# }

#my %restrictions;	# {'restriction_name' => 'module' => 'module_file_name',
						#								 'required-resourcetypes' => [ type1,type2,... ],
						#								 'description' => 'description text' 
						# }

# ----------- callbacks for modules... ----------------------

sub get_modules {
	return \%modules;
}

sub get_description { 
	my $ref = $modules{$_[0]};
	return ${$ref}{'description'}; 
}

# return a list of restrictions for given entity type
sub get_type_rests {
	my ($module, $restriction) = @_;
					
	my %types;
	foreach my $type (@{$modules{$module}{'tuple-restrictions'}{$restriction}{'required-resourcetypes'}}) {
		$types{$type} = 1;
	}
	foreach my $type (@{$modules{$module}{'resource-restrictions'}{$restriction}{'required-resourcetypes'}}) {
		$types{$type} = 1;
	}
				
	my @types = keys(%types);
	return \@types;
}

# return array of description for given restriction
#sub get_rest_desc {
#	my ($restriction) = @_;
#	my @desc = ("");
#	foreach my $mod (@{&get_rest_mod($restriction)}) {
#		push @desc, $modules{$mod}{'tuple-restrictions'}{$restriction}{'description'}; 
#		push @desc, $modules{$mod}{'resource-restrictions'}{$restriction}{'description'}; 
#	}
#	return \@desc;
#}

# returns a list of modules, that define the given restriction
sub get_rest_mod {
	my ($what) = @_;
	
	my @ret;
	foreach my $module (keys(%modules)) {
		foreach my $rest (keys(%{$modules{$module}{'resource-restrictions'}})) {
			if ($rest eq $what) {
				push @ret, $module;
			}
		}
		foreach my $rest (keys(%{$modules{$module}{'tuple-restrictions'}})) {
			if ($rest eq $what) {
				push @ret, $module;
			}
		}
	}
	
	return \@ret;
}

# returns a list of resource types required by the named restriction
sub get_rest_type {
	my ($what) = @_;
# todo: return the whole array..
	#my $ret = ${$restrictions{$what}{'required-resourcetypes'}}[0];
	
	my @ret;
	foreach my $module (keys(%modules)) {
		foreach my $rest (keys(%{$modules{$module}{'resource-restrictions'}})) {
			if ($rest eq $what) {
				@ret = (@ret, @{$modules{$module}{'resource-restrictions'}{$rest}{'required-resourcetypes'}});
			}
		}
		foreach my $rest (keys(%{$modules{$module}{'tuple-restrictions'}})) {
			if ($rest eq $what) {
				@ret = (@ret, @{$modules{$module}{'tuple-restrictions'}{$rest}{'required-resourcetypes'}});
			}
		}
	}
	
	return \@ret;
}

# checks whether the module for given restriction is activated or not
sub check_module {
	my ($what) = @_;
	my $form = &get_form;
	my $tv_m = $form->get_widget('treeview_modules')->get_model;
	my $state = 0;
	my $modules = &get_rest_mod($what);
	$tv_m->foreach(sub {
		my (undef,undef,$child_iter) = @_; 	 
		my ($name,$active) = $tv_m->get($child_iter,0,3);
		foreach my $module (@{$modules}) {
			if ($name eq $module) {
				if ($active) { $state = 1; }
				return 1;
			}
		}
		return 0;		 
	});
	return $state;
}

# ---------------------------------------------------------------
# load tablix1 modinfo
sub load_mod_info {
	my $form = &get_form;
#	my $path = $form->get_widget('entry_modpath')->get_text;
#	my @mods = readpipe ("ls -1 $path");

#	foreach my $mod (@mods) {
#		chop $mod;
#		if ($mod !~ /\.so$/) { next; }
	foreach my $mod (keys(%modules)) {

		my $description = readpipe("tablix_modinfo $mod");				
		my %module;
	
	# restrictions			
		foreach my $desc (split/\n/,$description) {	
			if ($desc =~ /(.*) restrictions\s*\:\s*(.*)$/) { 
				my $what = lc($1);
				my @rests = split/ /,$2;
				foreach my $restriction (@rests) {
					#push (@{$restrictions{$restriction}{'required-resourcetypes'}}, $what);
					#$restrictions{$restriction}{'module'} = $desc;
					if ($what eq 'tuple') {
						push (@{$module{'tuple-restrictions'}{$restriction}{'required-resourcetypes'}}, $what);
					} else {
						push (@{$module{'resource-restrictions'}{$restriction}{'required-resourcetypes'}}, $what);
					}
				}
			}
		# module options
			elsif ($desc =~ /Module options\s*\: (.*)/) { 
				my $what = 'module-options';
				my @rests = split/ /,$1;

				foreach my $restriction (@rests) {
					push (@{$module{$what}}, $restriction);
				}
			}
		}
	
	# store in the new way	
		$module{'basic-info'}{'filename'} = $mod;
		$module{'description'} = $description;
		$modules{$mod} = \%module;
	}
}

#load tablix2 modinfo
sub load_mod2_info {
	my $parser = XML::LibXML->new('load_ext_dtd' => 0);
		$parser->expand_entities(0);

	my $docpath = &get_form->get_widget('entry_modpath')->get_text;
	my $file_opened = $parser->parse_file("$docpath/modulesref.xml"); # build the XML

# TODO: failcheck
	
	my $root = $file_opened->getDocumentElement;
	my @modules = $root->getChildNodes;
	foreach my $module (@modules) {	

		if ($module->nodeName eq 'module') {
			my %module;

			foreach my $data ($module->getChildNodes) {
				my $what = $data->nodeName;

				if ($what eq 'description') {
			# todo: parse <example> and <p>
					my ($p, $ex, $pi, $ei) = &parse_descriptions ($data);
					if ($ei) { 
						$module{'description'} = "\n".$ex;
					} 
					if ($pi) { 
						$module{'description'} = "\n".$p;
					}
				} 
				elsif ($what =~ /^defined\-(.*)/) {
					my $type = $1;
					
					foreach my $info ($data->getChildNodes) {
						my %restriction;

						foreach my $rests ($info->getChildNodes) {
							if ($rests->nodeName eq 'description') {
								my ($p, $ex,$pi,$ei) = &parse_descriptions ($rests);
								if ($ei) { 
									$restriction{'description'} = "\n".$ex;
								} 
								if ($pi) { 
									$restriction{'description'} = "\n".$p;
								}
								#$restriction{'description'} = $ex."\n".$p;
							} 
							elsif ($rests->nodeName eq 'required-resourcetypes') {

								foreach my $para ($rests->getChildNodes) {
								    if ($para->nodeName eq 'all-resourcetypes') {
								        push (@{$restriction{'required-resourcetypes'}}, 'all');
								    } else {
									   my ($inf, $val) = &parse_sub_info ($para);
									   if ($inf and $val) {
										  push (@{$restriction{'required-resourcetypes'}}, $val);
									   }
									}
								}
							}
							else {
								my ($inf, $val) = &parse_sub_info ($rests);
								if ($inf and $val) {
									$restriction{$inf} = $val;
								}
							}
						}	

					# check for identifier
						my $name = $restriction{'name'};
						if ($name) {
			# mark tuple restrictions
							if ($type eq 'tuple-restrictions') {
								push (@{$restriction{'required-resourcetypes'}}, 'tuple');
							}
			
			# remember restrictions of the module
							if ($type eq 'options') {
								push (@{$module{'module-options'}}, $name); 
							}
							 
							$module{$type}{$name} = \%restriction; # type: 'tuple-restrictions' or 'resource'restrictions'
						}
					}
				}
				elsif ($what eq 'basic-info') {
					foreach my $info ($data->getChildNodes) {
						my ($inf, $val) = &parse_sub_info ($info);
						if ($inf and $val) {
							$module{$what}{$inf} = $val;
						}
					}
				}
				elsif (($what eq 'module-groups') or ($what eq 'required-resourcetypes')) {
					foreach my $info ($data->getChildNodes) {
						my ($inf, $val) = &parse_sub_info ($info);
						if ($inf and $val) {
							push (@{$module{$what}{$inf}}, $val);
						}
					}
				}
			}

			my $name = $module{'basic-info'}{'filename'};

# format the description - add all descriptions...

		$module{'description'} = "<b><big>".gettext("Module")." $name ".
														gettext("usage help")."</big></b>\n".$module{'description'};
		
		if ($module{'resource-restrictions'}) {
		 	$module{'description'} .= "\n\n<b><big>".gettext("Restrictions").":</big></b>\n";
  			foreach my $restriction (keys(%{$module{'resource-restrictions'}})) {
   			    if ($module{'resource-restrictions'}{$restriction}{'required-resourcetypes'}) {
   			      my @types = @{$module{'resource-restrictions'}{$restriction}{'required-resourcetypes'}};
			      $module{'description'} .= "\n\t<b>$restriction</b> : <i>".join(', ',@types)."</i>";
    		  }
    		}
		}

		if ($module{'tuple-restrictions'}) {
		 	$module{'description'} .= "\n\n<b><big>".gettext("Tuple restrictions").":</big></b>\n";
			foreach my $restriction (keys(%{$module{'tuple-restrictions'}})) {
				my @types = @{$module{'tuple-restrictions'}{$restriction}{'required-resourcetypes'}};
				$module{'description'} .= "\n\t<b>$restriction</b> : <i>".join(', ',@types)."</i>";
			}
		}
		
		if ($module{'options'}) {
		 	$module{'description'} .= "\n\n<b><big>".gettext("Options").":</big></b>\n";
			foreach my $restriction (keys(%{$module{'options'}})) {
				$module{'description'} .= "\n\t<b>$restriction</b>\t".$module{'options'}{$restriction}{'description'}."\n";
			}
		}

# dont remember the modules without identifiers		
		if ($name) {	
			$modules{$name} = \%module;
		}
}
	} # end of foreach module
	
	return keys(%modules);
}  

sub parse_descriptions {
	my ($seg) = @_;
	my %what = ('example' => 0, 'description' => 0);	# indicators
	my $p = "\n<b>".gettext("description").":</b> ";
	my $ex = "\n<b>".gettext("example").":</b><i> ";
	foreach my $para ($seg->getChildNodes) {
		my ($inf, $val) = &parse_sub_info ($para);	# inf: <p> / <pre>
		if ($val) {
			if ($inf eq 'p') { 
				$p .= $val; 
				$what{'description'} = 1;
			}
			elsif ($inf eq 'pre') { 
				$ex .= $val; 
				$what{'example'} = 1;
			}
		}
	}
	$ex .="</i>";
	return ($p, $ex, $what{'description'}, $what{'example'});
}

sub parse_sub_info {
	my ($info) = @_;
	if ($info->getFirstChild) {
		my $inf = $info->nodeName;
		my $val = $info->firstChild->data;
		return ($inf, $val);
	}
}

# ---------------------------------------------------------------

sub load_modules { 		# Load accesible modules and descriptions into "modules" clist.
	my $form = &get_form;
	my $path = $form->get_widget('entry_modpath')->get_text;
# some recomended values...
	my %values = (	'placecapability.so' => 40,
						'sametime.so' => 20,
						'timeplace.so' => 20,
						'student_freemorning.so' => 5,
						'student_walk.so' => 5,
						'student_holes.so' => 6,
						'teacher_freemorning.so' => 5,
						'teacher_holes.so' => 5,						
						'student_perday.so' => 2,
						'teacher_perday.so' => 2					
						);
	if (!-d $path) {
		&check(gettext("The modules path is not a directory.\nTablix modules will not work."),'error',1);
	} elsif (!-r $path) {
		&check(gettext("The modules directory is not readable.\nTablix modules will not work."),'error',1);
	} else {
	 	%modules = ();

		my $tablix = &get_tablix;

		opendir (MODS, $path);
		my @mods = readdir (MODS);
		foreach my $mod (@mods) {
			if ($mod =~ /.so$/) {
				$modules{$mod} = "";
			}
		}
		closedir MODS;

	 	if ($tablix eq 'tablix2') { &load_mod2_info; }
		elsif ($tablix eq 'tablix') { &load_mod_info; }

#		&debug_tree (\%modules, 'modules');
		
		my $tv_m = $form->get_widget('treeview_modules')->get_model;
		$tv_m->clear;
		
		foreach my $mod (keys(%modules)) {
	 		if (($mod =~ /\.so/) && ($mod !~ /export/)) {
	 			my $row = $tv_m->append; 
	 			my $val = $values{$mod};
					if (!defined $val) { $val = 0; }
				my $active = 0;
				if ($mod eq 'timeplace.so') { $active = 1; }
				$tv_m->set($row,0,$mod,1,$val,2,0,3,$active,4,"");
	 		}
	 	}
	}
}

# check for module restrictions and show/hide the appropriate entry
sub mod_opts {
	my ($form,$name,$opts) = @_;
	my $modopts = ${$modules{$name}}{'module-options'};	
 	if ($modopts) {
 		$form->get_widget('entry_mod_opts')->set('sensitive',1);
 		$form->get_widget('button_mod_opts_use')->set('sensitive',1);		
 	} else {
 		$form->get_widget('entry_mod_opts')->set('sensitive',0);
 		$form->get_widget('button_mod_opts_use')->set('sensitive',0);
	}
	if ($opts) { 
		$form->get_widget('entry_mod_opts')->set_text("$opts");
	} elsif ($modopts) {
		$form->get_widget('entry_mod_opts')->set_text(join(":;",@{$modopts}).":;");
	} else {
		$form->get_widget('entry_mod_opts')->set_text("");
	}
}

sub mod_desc {
	my ($form,$name) = @_;
	my $description = &get_description($name);
	my $tablix = &get_tablix;
	if (defined $description) { 
		$form->get_widget('label_modinfo')->set_markup($description);
	} 
	else {
		$form->get_widget('label_modinfo')->set_text(gettext("tablix_modinfo didn't find 
any info about this module.
This could happend because:\n
- you don't have tablix_modinfo in your path,\n
- this module does not function properly,\n
- this module is an internal module\n"));
	}
}

# ------ modinfo window --------------------------------
sub on_toggletoolbutton_options_toggled {
	my ($who) = @_;
	my $form = &get_form;
	$form->get_widget('window_rests')->set('visible' => $who->get_active);
	$form->get_widget('label_names')->set_text(gettext("Select an entity to add restrictions to, by right clicking on it or by clicking the appropriate (down) button. ")); 
	$form->get_widget('window_rests')->set_keep_above($who->get_active);
}
sub on_button_ok_rests_clicked {
	&ok_rests;
}
sub on_button_close_rests_clicked {
	&get_form->get_widget('toggletoolbutton_options')->set_active(0);
}
sub on_window_rests_delete_event {
	&get_form->get_widget('toggletoolbutton_options')->set_active(0);
	return 1;
}
sub load_rests {		# vpise prave vrednosti za dialog_rests
	# rests so vedno oblike: "rest_type1:rest_val1,rest_val2,...;rest_type2:..."
	my ($what) = @_;
	my $form = &get_form;
   $widgets{'what'} = $what;
	$form->get_widget('toggletoolbutton_options')->set_active(1);   
	if ($what) { &load_rests_editor($what); 
	} else { $form->get_widget('label_names')->set_text(gettext("Select an entity to add restrictions to, by right clicking on it or by clicking the appropriate (down) button. ")); }
}

sub ok_rests {
	my $form = &get_form;
	my $tvr = $form->get_widget('treeview_rests');
	my $what = $widgets{'what'};
	my $text = "";	
	my @list = ""; my $counter = 0; 
	
	$tvr->get_model->foreach(sub {
	 		(undef, undef, my $iter) = @_;
	 		my ($rest_type,$rest_vals,$name,$active) = $tvr->get_model->get($iter,0,1,2,3);
	 # na vsak nacin aktivira ustrezne module
	 		if ($active) {
			#if (defined $rest_vals) {
	 			my $row = &find_clist_row("modules",$name);
	 	# check that the module exists
				if ($row ne "new") {
	 				my $tvm = $form->get_widget('treeview_modules')->get_model;
					my $iter = $tvm->get_iter_from_string($row);
	            $tvm->set($iter, 3, '1');	
		# set weigth to at least 1
					my $val = $tvm->get($iter,1);
 	 				if (!$val) { 
						$tvm->set($iter,1,'1'); 
					}
	 	# add text
	 				if ((defined $rest_vals) and ($rest_vals ne "")) {
						$text = "$rest_type:$rest_vals;".$text; 
					}
	 			}
	 		}
			return 0; 
	 	});
		$form->get_widget("entry\_$what\_rests")->set_text($text);
	 	if (defined $what) {
			if ($what eq "tt") {
# todo: add special handling for fixed-day nad fixed-period
				&on_button_tt_use_clicked;
		 	} else { 
				if ($form->get_widget("entry_$what\_name")->get_text ne "") {
					&add_row($what); 
				}
			}
	} else { &check(gettext("Internal error: I don\'t know where to append these restrictions, or no restrictions were set."),'error',1); }
}
# ------------------------------------------------------------------------------------------
sub set_smart_view {
	my ($restriction,$restriction_value,$iter) = @_;
	my $form = &get_form;
	my $tvr = $form->get_widget('treeview_rests');
	my $table = $form->get_widget('table_rests');

# this is where fields will be appended; default to the end of the table
	my $cols = $table->get('n-columns');
	my $rows = $table->get('n-rows');

# descriptions; todo: get from modules
	my %descriptions = (		
		'consecutive' => gettext("Repeats of this event should be consecutive:"),		
		'fixed-day' => gettext("Schedule on this day:"),
		'fixed-period' => gettext("Schedule on this period:"),
		'capability' => gettext("Require special room:"),
		'free-day' => gettext("Don't schedule on this day:"),		
		'day-off' => gettext("Don't schedule on this day:"),
		'capability-place' => gettext("Require special room:"),
		'preferred-period' => gettext("Prefer this period:"),
		'preferred-day' => gettext("Prefer this day:"),		
		'preferred-room' => gettext("Prefer this room:"),
		'teacher-maxperday' => gettext("Maximum allowed lessons per day:"),
		'morning-subject' => gettext("This subject should be scheduled before:"),
		'conflicts-with' => gettext("These should never be scheduled at the same time:"),		
		'group' => gettext("These classes belong to a group:"),		
		'same-time-as' => gettext("These classes must be scheduled simultaniously:"),
		'teacher-also' => gettext("Add more teachers:"),
		'ignore-sameday' => gettext("Activate to ignore checking for multiple occurances of the same subject."),
		'double-period' => gettext("Select another subject, to link into double period:"),		
		'free-period' => gettext("Select a day and a period at which this class should be free:")		
	);

	if (!$descriptions{$restriction}) {
 		$descriptions{$restriction}  = gettext("I'm sorry, I don't know \nthis restriction well enough").
		": $restriction.";
	}

# check if alredy exists
	foreach my $cell ($table->get_children) {
		if ($cell->get_name eq $restriction) {
			my $row = $table->child_get($cell,'top-attach');
			foreach my $celll ($table->get_children) {
				if ($table->child_get($celll,'top-attach') == $row) {
					$celll->destroy;
				}
			}
			$rows = $row;
			last;
		}
	}

# draw description label
	$table->resize($rows + 1,3);
	my $label = new Gtk2::Label();
		$label->set_use_markup(1);
		$label->set_markup('<b>'.$descriptions{$restriction}.'</b>'); 
		$label->set_name($restriction);
		$label->set('justify' => 'left');
		$label->set('wrap' => 1);
		$label->set('width-request' => 200);
		$table->attach($label,0,1,$rows + 0,$rows + 1,'expand','expand',2,2);
		$label->show;

# draw entry or something
	my $type_entry;
# ----------------------------------------------------
	if ($restriction =~ /capability/) {
 	# draw the elements		
		my $combobox = Gtk2::ComboBoxEntry->new_text;
			my %temp;
			my $tw_c = $form->get_widget('treeview_classrooms')->get_model;
			$tw_c->foreach(sub {
	 	  		my (undef,undef,$child_iter) = @_; 	
				my $idd = $tw_c->get($child_iter,1); 
	 	  		foreach my $id (split/; /,$idd) {
					if (((split/:/,$id)[0]) eq $restriction) {
	 					my $i = (split/:/,$id)[1];
	 					foreach my $d (split/,/,$i) {	
	 						if ($d) { $temp{$d} = ""; }
	 					}
					}
				}
				return 0;
	 	  	});
			foreach my $temp (sort(keys(%temp))) {
				$combobox->append_text($temp);
			}
		my $align = new Gtk2::Alignment(0.5,0.5,0,0);
			$align->add($combobox);
			$align->show;
			$table->attach_defaults($align,1,2,$rows + 0,$rows + 1);
			$combobox->show;
			$type_entry = ($combobox->get_children)[0];		
# ----------------------------------------------------
	} elsif (($restriction eq "preferred-period") or 
				($restriction eq "preferred-day") or 
				($restriction eq "preferred-room") or
				($restriction eq "free-day") or
				($restriction eq "fixed-period") or 
				($restriction eq "fixed-day") or 
				($restriction eq "day-off")
				) {
		my $what = (split/-/,$restriction)[1];
 	  	my $days = int($form->get_widget('entry_days')->get_text);
		my $pers = int($form->get_widget('entry_periods')->get_text);
		$table->resize(1,3);
 # draw the elements		
		my $combobox = Gtk2::ComboBoxEntry->new_text;
		
			if (($what eq "day") or ($what eq 'off')) { 
				for (my $counter = 0; $counter < $days; $counter++) {  
					$combobox->append_text($counter); } }
			if ($what eq "period") { 
				for (my $counter = 0; $counter < $pers; $counter++) { 
					$combobox->append_text($counter); } }
			if ($what eq "room") { 
	 			my $tw_c = $form->get_widget('treeview_classrooms')->get_model;
	 			$tw_c->foreach(sub {
	 	 	  		my (undef,undef,$child_iter) = @_; 	
	 	  	 	  	$combobox->append_text($tw_c->get($child_iter,0));
					return 0;
	 	  	 	});
			}
		my $align = new Gtk2::Alignment(0.5,0.5,0,0);
			$align->add($combobox);
			$align->show;						
			$table->attach_defaults($align,1,2,$rows + 0,$rows + 1);
			$combobox->show;
			$type_entry = ($combobox->get_children)[0];			
# ----------------------------------------------------
	} elsif (($restriction eq "teacher-maxperday") or ($restriction eq "morning-subject")) {
		my $what = (split/-/,$restriction)[1];
		my $pers = int($form->get_widget('entry_periods')->get_text);
		$table->resize(1,3);
 # draw the elements		
		my $combobox = Gtk2::ComboBoxEntry->new_text;				
			for (my $counter = 0; $counter < $pers; $counter++) { $combobox->append_text($counter); } 
		my $align = new Gtk2::Alignment(0.5,0.5,0,0);
			$align->add($combobox);
			$align->show;
			$table->attach_defaults($align,1,2,$rows + 0,$rows + 1);
			$combobox->show;
			$type_entry = ($combobox->get_children)[0];			
# ----------------------------------------------------
	} elsif (($restriction eq "conflicts-with") or ($restriction eq "group") or ($restriction eq "same-time-as")) {
		$table->resize(1,3);
 # draw the elements		
		my $combobox = Gtk2::ComboBoxEntry->new_text;			
	 			my $tw_c = $form->get_widget('treeview_classs')->get_model;
	 			$tw_c->foreach(sub {
	 	 	  		my (undef,undef,$child_iter) = @_; 	
	 	  	 	  	$combobox->append_text($tw_c->get($child_iter,0));
					return 0;
	 	  	 	});
		my $align = new Gtk2::Alignment(0.5,0.5,0,0);
			$align->add($combobox);
			$align->show;
			$table->attach_defaults($align,1,2,$rows + 0,$rows + 1);
			$combobox->show;
			$type_entry = ($combobox->get_children)[0];			
# ----------------------------------------------------
	} elsif ($restriction eq "teacher-also") {
		$table->resize(1,3);
 # draw the elements		
		my $combobox = Gtk2::ComboBoxEntry->new_text;				
		my %list;
	 			my $tw_c = $form->get_widget('treeview_teachers')->get_model;
	 			$tw_c->foreach(sub {
	 	 	  		my (undef,undef,$child_iter) = @_; 	
	 	  	 	  	$list{$tw_c->get($child_iter,0)} = "";
					return 0;
	 	  	 	});
			foreach my $t (keys(%list)) { $combobox->append_text($t); }
		my $align = new Gtk2::Alignment(0.5,0.5,0,0);
			$align->add($combobox);
			$align->show;
			$table->attach_defaults($align,1,2,$rows + 0,$rows + 1);
			$combobox->show;
			$type_entry = ($combobox->get_children)[0];	
# ----------------------------------------------------
	} elsif (($restriction eq "ignore-sameday") or ($restriction eq 'consecutive'))  {
		$table->resize(1,3);
 # draw the elements		
		my $checkbox = Gtk2::CheckButton->new;
			$table->attach_defaults($checkbox,1,2,$rows + 0,$rows + 1);
			$checkbox->set_active($restriction_value);
			$checkbox->show;
		
			my $button = Gtk2::Button->new_from_stock('gtk-add');
			$button->signal_connect(clicked=> sub { 
					my $val = $checkbox->get_active;
	 	  			my $row = &find_clist_row("rests",$restriction);
	 	  			if ($row ne "new") {
						$tvr->get_model->set($iter,1,$val,3,'1');
	 	  			}
					#&on_okbutton_rests_clicked;
				});
		my $align = new Gtk2::Alignment(0.5,0.5,0,0);
			$align->add($button);
			$align->show;
			$table->attach_defaults($align,2,3,$rows + 0,$rows + 1);
			$button->show;

# ----------------------------------------------------
	} elsif ($restriction eq "double-period") {
		$table->resize(1,3);		
		my @what = (split/\n/,$form->get_widget('label_names')->get_text);	
		my $class_name = (split/: /,$what[0])[1];
			$class_name =~ s/, //g;
 # draw the elements		
		my $combobox = Gtk2::ComboBoxEntry->new_text;	
		my $tw = $form->get_widget('treeview_tt')->get_model;
		my $class_iter = &find_clist_row('tt',$class_name);
		if ($class_iter ne 'new') { 			
			$class_iter = $tw->get_iter_from_string($class_iter);
			$combobox->append_text($tw->get($class_iter,1)); 
			if ($tw->iter_has_child($class_iter)) {
				for (my $iter = $tw->iter_children($class_iter); $iter; $iter = $tw->iter_next($iter)) {
					$combobox->append_text($tw->get($iter,1));
				}
			} 
		}
		my $align = new Gtk2::Alignment(0.5,0.5,0,0);
			$align->add($combobox);
			$align->show;
		$table->attach_defaults($align,1,2,$rows + 0,$rows + 1);
		$combobox->show;
		$type_entry = ($combobox->get_children)[0];			
# ----------------------------------------------------
	} elsif (($restriction eq "free-period")) {
		my $what = (split/-/,$restriction)[1];
 	  	my $days = int($form->get_widget('entry_days')->get_text);
		my $pers = int($form->get_widget('entry_periods')->get_text);
		$table->resize(2,3);
		#$table->attach_defaults($label,0,1,0,2);
 # draw the elements		
		my $combobox_day = Gtk2::ComboBoxEntry->new_text;	
		my $combobox_per = Gtk2::ComboBoxEntry->new_text;	
			for (my $counter = 0; $counter < $days; $counter++) { $combobox_day->append_text($counter); } 
			for (my $counter = 0; $counter < $pers; $counter++) { $combobox_per->append_text($counter); } 
				
		my $align2 = new Gtk2::Alignment(0.5,0.5,0,0);
			$align2->add($combobox_day);
			$align2->show;
			$table->attach_defaults($align2,1,2,$rows + 0,$rows + 1);
		my $align1 = new Gtk2::Alignment(0.5,0.5,0,0);
			$align1->add($combobox_per);
			$align1->show;
			$table->attach_defaults($align1,1,2,$rows + 1,$rows + 2);
			$combobox_day->show;
			$combobox_per->show;
			my $type_entry_day = ($combobox_day->get_children)[0];
			my $type_entry_per = ($combobox_per->get_children)[0];	

			my $button = Gtk2::Button->new_from_stock('gtk-add');
			$button->signal_connect(clicked=> sub { 
					my $val_day = $type_entry_day->get_text;
					my $val_per = $type_entry_per->get_text;
	 	 			my $val;
					if (($val_day eq "") or ($val_per eq "")) {
						$val = "";
					} else {
						$val = "$val_day $val_per";
					}
					my $active = 1;
	 	 			if ($val eq "") { 
	 	 				$active = 0; 
	 	 				$restriction_value = "";
	 	 			} elsif (defined $restriction_value) { 
	 	 				$restriction_value = &strip_commas("$val,".$restriction_value); 
	 	 			} else { 
	 	 				$restriction_value = $val; 
	 	 			}
					$tvr->get_model->set($iter,1,$restriction_value,3,$active);		
					$form->get_widget('button_ok_rests')->clicked;
				});
		my $align = new Gtk2::Alignment(0.5,0.5,0,0);
			$align->add($button);
			$align->show;
			$table->attach_defaults($align,2,3,$rows + 0,$rows + 1);
			$button->show;
			$table->child_set($label,'bottom-attach' => $rows + 2);

# -----------------------------------------------------
# if i dont know it...
	} 
	
	if ($type_entry) {
		if (defined $restriction_value) { $type_entry->set_text($restriction_value); }
		my $button = Gtk2::Button->new_from_stock('gtk-add');
#		my $image = $button->get_image;
#		$button->set_label('');
#		$button->set_image($image);
		$button->signal_connect(clicked => sub { 
			my $val = $type_entry->get_text;
			my $active = 1;
			if ($val eq "") { 
				$active = 0; 
				$restriction_value = "";
			} elsif (defined $restriction_value) { 
				$restriction_value = &strip_commas("$val,".$restriction_value); 
			} else { 
				$restriction_value = $val; 
			}
			$tvr->get_model->set($iter,1,$restriction_value,3,$active);
			$form->get_widget('button_ok_rests')->clicked;
		});
		my $align = new Gtk2::Alignment(0.5,0.5,0,0);
			$align->add($button);
			$align->show;
		$table->attach_defaults($align,2,3,$rows + 0,$rows + 1);
		$button->show;
	}	
}

sub on_treeview_rests_cursor_changed {
 	my ($tvr) = @_;
 	my $form = &get_form;
 	my $label = $form->get_widget('label_rest_desc');
 
 	(my $path, my $col) = $tvr->get_cursor(); 
 	my $iter = $tvr->get_model->get_iter($path);
 	my ($restriction, $restriction_value,$module) = $tvr->get_model->get($iter,0,1,2);

	my $modules_for = &modules_for($form->get_widget('label_names')->get_text);
	my $description = "";	

	if ($modules_for eq gettext('Tuple')) {
		$description = $modules{$module}{'tuple-restrictions'}{$restriction}{'description'};	
	} else {
		$description = $modules{$module}{'resource-restrictions'}{$restriction}{'description'};
	}
	
	$label->set_text($description);
}

# return the type of entitity, for which the dialog is currently shown, 
# based on the last word of the label's text 
sub modules_for {
	my ($text) = @_;
	my @text = split/\n/,$text;
	$text = shift(@text);
	my $trans = gettext("Settings for");
	$text =~ /$trans (.*)$/;
	return $1;
}

########################################################################3
sub load_rests_editor {
	my ($what) = @_;
	my $form = &get_form;
	my $twm = $form->get_widget('treeview_rests');
	my $dialog = $form->get_widget('window_rests');
	my $label = $form->get_widget('label_names');
	my %rests_s;
	my $name;
	my $What = ucfirst($what);
	my $rests;
	my $tablix = &get_tablix;

		$form->get_widget('label_rest_desc')->set_text("");

	my %translate = (	'class'		=> {	'tablix' =>	'class',
													'tablix2' => 'class'
																					},
							'classroom' =>	{  'tablix' => 'room',
													'tablix2' => 'room'
																					},
							'subject'	=> {	'tablix' => 'subject',
													'tablix2' => 'subject'
																					},
							'teacher'	=> { 	'tablix' => 'subject',
													'tablix2' => 'teacher'
																					},
							'tt'	=> { 	'tablix' => 'tuple',
											'tablix2' => 'tuple'
																		}
						);
# get names
	if ($what eq 'tt') {
		$What = 'Tuple';
	 	my $teacher = $form->get_widget('combo_entry_tt_teacher')->get_text();
	 	my $subject = $form->get_widget('combo_entry_tt_subject')->get_text();
	 	my $class = $form->get_widget('combo_entry_tt_class')->get_text();
		$dialog->set_title(gettext($What).gettext("\'s restrictions editor"));
		$label->set_text(gettext("Settings for")." ".gettext($What)."\n". 
								gettext("class:")." $class, \n".
								gettext("subject:")." $subject, \n".
								gettext("teacher:")." $teacher");

	} elsif ($form->get_widget("entry_$what\_name")) { 
		$name = $form->get_widget("entry_$what\_name")->get_text;
		$dialog->set_title(gettext($What).gettext("\'s restrictions editor"));
		$label->set_text(gettext("Settings for")." ".gettext($What)."\n".gettext($what).": $name");

	} elsif ($what =~ /^combinations_/) {
		my $tw = $form->get_widget("treeview_$what".'s');

		(my $path, my $col) = $tw->get_cursor(); 
		if (defined $path) {
	 		my $iter = $tw->get_model->get_iter($path);
	 		$name = $tw->get_model->get($iter,0);	
		
		$what =~ s/combinations_//;
		$What = ucfirst($what);

		$dialog->set_title(gettext($What).gettext("\'s restrictions editor"));
		$label->set_text(gettext("Settings for")." ".gettext($What)."\n".gettext($what).": $name");
	
		my $row = &find_clist_row($what.'s',$name);
		if ($row ne 'new') {
			my $tv = $form->get_widget("treeview_$what".'s');
			$tv->set_cursor($tv->get_model->get_path($tv->get_model->get_iter_from_string($row)));
		}
		}
	}

	if ($What eq "Teacher") { 
		$What = "Subject"; 
		my $text = $label->get_text;
		my $subject = $form->get_widget("entry_teacher_subjects")->get_text;
		$label->set_text($text.",\n ".gettext("subject").": $subject");
	} elsif ($What eq "Classroom") { 
		$What = "Room"; 
	}

# alredy set restrictions	
	if ($form->get_widget("entry_$what\_rests")) { 
		$rests = $form->get_widget("entry_$what\_rests")->get_text; 
		foreach my $rest (split/\;/,$rests) { 			
			my @spec = split/:/,$rest;
			if ($spec[1]) { 
				foreach my $spec (split/\,/,$spec[1]) {
					if ($rests_s{$spec[0]}) { 
						$rests_s{$spec[0]} = "$spec,$rests_s{$spec[0]}";
					} else {	
						$rests_s{$spec[0]} = $spec; 
					}
					$rests_s{$spec[0]} =~ s/\,$//g;
				}
			}
		}
	}

# clear the table
	my $table = $form->get_widget('table_rests');
	my @children = $table->get_children;
	foreach my $child (@children) { $child->destroy; }

# get appropriate restrictions from modules list	
	if ($twm) {
	$twm->get_model->clear;
	my $tvm = $form->get_widget('treeview_modules')->get_model;
	$tvm->foreach(sub {	
 	 	my (undef,undef,$child_iter) = @_; 	 	 		
 	 	my ($module,$active) = $tvm->get($child_iter,0,3);	

		my $modules = &get_modules;
	# all restrictions of every module
		my $rests;
		if ($what eq 'tt') {
			$rests = ${$modules}{$module}{'tuple-restrictions'};
		} else {
			$rests = ${$modules}{$module}{'resource-restrictions'};
		}
		foreach my $restriction (keys(%{$rests})) {
			my @types = @{&get_type_rests($module, $restriction)};

		# all defined types of entities
			foreach my $type (@types) {
			
			# if it's the right one, write it to the list
					if (($type eq $translate{$what}{$tablix}) or ($type eq 'all')) {
						my $value = $rests_s{$restriction};
						my $row = $twm->get_model->append(undef); 
						$twm->get_model->set($row,0,$restriction,1,$value,2,$module,3,$active);
			
			# and prepare the nice one...
						&set_smart_view($restriction,$value,$row);
					}
				}
			}

		return 0;
		});
	}
# reconnect ok button
	if ($widgets{'ok_id'}) { 
		$form->get_widget('button_ok_rests')->signal_handler_disconnect($widgets{'ok_id'}); }
	my $ok_id = $form->get_widget('button_ok_rests')->signal_connect(clicked => 
																			sub { &ok_rests($form,$twm,$what); });
	$widgets{'ok_id'} = $ok_id;
}

sub draw_rests_editor {
# draw the treeview
	my $form = &get_form;
 	my $drevo = new Gtk2::TreeStore('Glib::String',
												'Glib::String',
												 'Glib::String',
												  'Glib::Boolean',
												   'Glib::String');
	my $tvr = $form->get_widget('treeview_rests');
		$tvr->set_model($drevo);
	#my $tvr = Gtk2::TreeView->new_with_model($drevo);
		$tvr->set('headers-clickable',1);
 		$tvr->set('rules-hint',1);
		$tvr->signal_connect('cursor_changed' => \&on_treeview_rests_cursor_changed);
	my @columns = (gettext("Name"),
						gettext("Value"),
						gettext("Module"),
						gettext("Active"),
						gettext("Notes"));
 	for (my $c = 0; $c <= $#columns; $c++) {
 		my $col;
		if ($c == 1) { 
			my $renderer = new Gtk2::CellRendererText();
			$col = Gtk2::TreeViewColumn->new_with_attributes($columns[$c],$renderer,'text' => $c);
 			$renderer->set('editable' => TRUE); 
  			$renderer->signal_connect (edited => sub {
	           my ($cell, $text_path, $new_text) = @_;
				  my $iter = $drevo->get_iter_from_string($text_path);
	           $drevo->set($iter, '1', $new_text);
				  my $s = $drevo->get($iter,0);
				  &set_smart_view($s,$new_text,$iter);
 			 });
 		} elsif ($c == 3) { 
 			my $renderer = new Gtk2::CellRendererToggle();
			$renderer->set('activatable' => '1');
   			$renderer->signal_connect('toggled' => sub {
  					my ($render,$row) = @_;	
					my $iter = $drevo->get_iter_from_string($row);
					my $val = $drevo->get($iter, 3);
					$drevo->set($iter, 3, !$val);
  				});
			$col = Gtk2::TreeViewColumn->new_with_attributes($columns[$c],$renderer,'active' => $c);
		} elsif ($c == 4) { 
			my $renderer = new Gtk2::CellRendererText();
			$col = Gtk2::TreeViewColumn->new_with_attributes($columns[$c],$renderer,'text' => $c);
 			$renderer->set('editable' => TRUE); 
  			$renderer->signal_connect (edited => sub {
	           my ($cell, $text_path, $new_text) = @_;
				  my $iter = $drevo->get_iter_from_string($text_path);
	           $drevo->set($iter, '4', $new_text);
 			 });
		} else { 
			my $renderer = new Gtk2::CellRendererText();
			$col = Gtk2::TreeViewColumn->new_with_attributes($columns[$c],$renderer,'text' => $c);
		}
		$col->set_sort_column_id($c);
 		$tvr->append_column($col);
		$col->set_resizable(1);
 	}
	my $white = Gtk2::Gdk::Color->new(65535,65535,65535);
	$form->get_widget('eventbox_label_rests_note')->modify_bg('normal',$white);
	$form->get_widget('eventbox_label_rests_name')->modify_bg('normal',$white);	
#	$form->get_widget('eventbox_buttons_rests')->modify_bg('normal',$white);
}

sub create_mod_context {
	my ($menu, $what) = @_;
	
}


return 1;
