#!/usr/bin/perl -w

# use the ToolKit
use Tk;
use Tk::Text;
use Tk::FileSelect;
use Pod::Text;

# Global parameters to be changed if needed

# The variables we want to be safed in the configuration file
@SaveVariables = qw(delta begin_from_bottom viewer
		    radius_inner tickmarks 
		    print_circle_boundaries
		    begin_from_left[0] begin_from_left[1]
		    number_of_labels
		    text[0][0] text[0][1] text[0][2] text[0][3]
		    text[1][0] text[1][1] text[1][2] text[1][3]
		    dummy[0][0] dummy[0][1] dummy[0][2] dummy[0][3]
		    dummy[1][0] dummy[1][1] dummy[1][2] dummy[1][3]
		    circle_radius[0][0] circle_radius[0][1]
		    circle_radius[0][2] circle_radius[0][3]
		    circle_radius[1][0] circle_radius[1][1]
		    circle_radius[1][2] circle_radius[1][3]
		    eps_file_label[0] eps_file_label[1]
		    eps_filename[0] eps_filename[1]
		    shift_x shift_y scale_x scale_y
		    x_scale y_scale
		    fontfamily[0] fontfamily[1]
		    fontfamily[2] fontfamily[3]
		    fontfamily[4] fontfamily[5]
		    fontfamily[6] fontfamily[7]
		    scalefont[0] scalefont[1]
		    scalefont[2] scalefont[3]
		    scalefont[4] scalefont[5]
		    scalefont[6] scalefont[7]
		   );

use vars (@SaveVariables);

# Then we get some default values
$pi = 3.14159;

default_attributes();
default_text();

defaults();
default_colors();

# read the command-line for a additional configuration file

my ($commandline) = @ARGV;

if (defined $commandline) {
  read_configuration($commandline) if -f $commandline;
}
else {
  read_configuration();
}

# then we need the main-window
$mw = MainWindow -> new;
$mw -> title("cd-circleprint");
# Something which some windowmanager semems to nedd
$mw -> geometry("+0+0");

# some key-bindings
# We want to exit the program with C-q
$mw -> bind("<Control-q>", [sub {exit}]);
$mw -> bind("<Control-l>", [sub {&print_label}]);
$mw -> bind("<Control-p>", [sub {&preview}]);
$mw -> bind("<Control-s>", [sub {&write_configuration}]);

# Now we want a frame on the top of the window for the menus
$menu_frame = $mw -> Frame(-relief => 'raised', -bd => 2) -> pack(-side => 'top',
								  -fill => 'x',
								  -anchor => 'n',
								  -expand => '1');

$menu_frame -> Menubutton(-text => "File",
                          -underline => 0,
			  -menuitems => [
					 ['command' => "load configuration",
					  -command => \&read_configuration,
					  -underline => 0],
					 ['command' => "save configuration",
					  -command => \&write_configuration,
					  -underline => 0],
					 "-",
					 ['command' => "save label",
					 -command => \&save_ps_file,
					  -underline => 0],
					 "-",
					 ['command' => "preview",
					  -command => \&preview,
					  -underline => 0],
					 "-",
					 ['command' => "exit C-q",
					  -command => sub{exit},
					  -underline => 1]
				       ]) -> pack(-side => 'left');

$menu_labeloptions = $menu_frame -> Menubutton(-text => "Label-options",
					       -underline => 0) -> pack(-side => 'left');

$menu_labeloptions -> command(-label => "Fonts and colours",
			      -command => \&get_fontattributes,
			      -underline => 0);

$menu_labeloptions -> command(-label => "Angle",
			      -command => \&get_starting_angle,
			      -underline => 0);

$menu_labeloptions -> command(-label => "Radii",
			      -command => \&set_circle_radius,
			      -underline => 1);

$menu_labeloptions -> command(-label => "Page deformation",
			      -command => \&set_page_scaling,
			      -underline => 0 );

$menu_labeloptions -> command(-label => "Distances",
			      -command => \&set_distances,
			      -underline => 0 );

$menu_labeloptions -> checkbutton(-label => "tick marks",
				  -variable => \$tickmarks);

$menu_labeloptions -> checkbutton(-label => "circle boundaries",
				  -variable => \$print_circle_boundaries);

$menu_labeloptions -> command(-label => "Graphics",
			      -command => \&get_graphics,
			      -underline => 0 );

$menu_options = $menu_frame -> Menubutton(-text => "Options",
					  -underline => 0) -> pack(-side => 'left');

$menu_options -> command(-label => "Previewer",
			 -command => \&get_previewer,
			 -underline => 0);

$menu_options -> command(-label => "Load options",
			 -command => \&read_configuration,
			 -underline => 0);

$menu_options -> command(-label => "Save options",
			 -command => \&write_configuration,
			 -underline => 0);

$menu_frame -> Button(-text => "label", -command => \&print_label) -> pack(-side => 'left');
$menu_frame -> Button(-text => "preview", -command => \&preview) -> pack(-side => 'left');

## The help entry
$menu_help = $menu_frame -> Menubutton(-text => "Help",
				       -underline => 0) -> pack(-side => 'right');
$menu_help -> command(-label => "Help",
		      -command => \&help_window,
		      -underline => 0);
$menu_help -> command(-label => "Info",
		      -command => \&info_window,
		      -underline => 0);

# Now we create two frames for the text-entry widgets

$circle_frame = $mw -> Frame(-label => "circles",
			     -borderwidth => 15,
			     -relief => 'groove') -> pack(-side => 'bottom',
							 -fill => 'x');

$textfield_frame = $mw -> Frame(-label => "textfields",
				-borderwidth => 15,
				-relief => 'groove') -> pack(-side => 'bottom');

# First two frames for the circles

$circle_text_frame[0] = $circle_frame -> Frame(-label => "bottom label",
			   -borderwidth => 5,
			   -relief => 'groove') -> pack(-side => 'left');
$circle_text_frame[1] = $circle_frame -> Frame(-label => "top label",
			    -borderwidth => 5,
			    -relief => 'groove') -> pack(-side => 'right');


# Then two for the textfields

$textfield_frame[0] = $textfield_frame -> Frame(-label => "bottom label",
			   -borderwidth => 5,
			   -relief => 'groove') -> pack( -fill => "both", -side => 'left');
$textfield_frame[1] = $textfield_frame -> Frame(-label => "top label",
			    -borderwidth => 5,
			    -relief => 'groove') -> pack( -fill => "both", -side => 'right');


# Now create the widgets for the text

for ( my $j=0;$j<$number_of_labels;$j++) {
  for (my $i=0;$i<4;$i++ ) {
#!!!!!!!!!!!!! Entry Text
    $textfield_entry[$j][$i] = $textfield_frame[$j] -> Text(-background => "#ffffff",
							     -font => r16,
							     -height => 4,
							     -width => 46)
      -> pack( -fill => "both", -ipadx => 10, -ipady => 10 );

    if (defined $dummy[$j][$i]) {
      $textfield_entry[$j][$i] -> insert('end',$dummy[$j][$i]);
    }
    else
      {
	$textfield_entry[$j][$i] -> insert('end'," ");
      }

    $entry[$j][$i] = $circle_text_frame[$j] -> Entry(-textvariable => \$text[$j][$i],
						     -background => $backgroundcolor)
      -> pack( -ipadx => 10, -ipady => 10 );

    $font[$i] = $entry[$j][$i] -> fontCreate();
    $font[$i+4] = $textfield_entry[$j][$i] -> fontCreate();

    $which_circle = $i;
    $scale = $scalefont[$i];
    configure_fonts($j);
  }
}

$circle_text_frame[0] -> Button(-text => "clear",
				-command => sub{clear_circle_text (0)} ) -> pack();
$circle_text_frame[1] -> Button(-text => "clear",
				-command => sub{clear_circle_text (1)} ) -> pack();

$textfield_frame[0] -> Button(-text => "clear",
				-command => sub{clear_textfields (0)} ) -> pack();
$textfield_frame[1] -> Button(-text => "clear",
				-command => sub{clear_textfields (1)} ) -> pack();

############################

MainLoop;

#######################
sub add_font_from_entry {

  $fontlistbox -> insert('end', $fontentry -> get() );
  push(@fontnames,$fontentry -> get());
}

#######################
sub clear_circle_text {
  my $j = shift;

  for (my $i=0; $i < 4; $i++ ) {
    $text[$j][$i] = "";
    $entry[$j][$i] -> configure(-text);
  }
  set_fontattributes ;
}

#######################
sub clear_textfields {
  my $j = shift;

  for (my $i=0; $i < 4; $i++ ) {
    $textfield_entry[$j][$i] -> delete ("1.0",'end'); # configure(-text);
  }
  set_fontattributes ;
}
#######################
sub configure_fonts {
  # It is not possible to use the size from the perl-tk fonts, because the perl-tk
  # uses the nearest matching font on the system but we want exact postscript fonts

  my $j = shift;

  $scalefont[$which_circle] =   $scale ;

  if ($which_circle < 4) {
    $entry[$j][$which_circle] -> fontConfigure($font[$which_circle],
					       -size => $scale,
					       -family => $fontfamily[$which_circle]);

    $entry[$j][$which_circle] -> configure(-font => $font[$which_circle]);
  }
  else {
    $textfield_entry[$j][$which_circle-4] -> fontConfigure($font[$which_circle],
					       -size => $scale,
					       -family => $fontfamily[$which_circle]);

    $textfield_entry[$j][$which_circle-4] -> configure(-font => $font[$which_circle]);
  }
}

#######################
sub default_colors {

  for ($which_circle = 0; $which_circle <8;$which_circle++) {
    $ps_color[$which_circle] = " 0 0 0 ";
    for ($j=0;$j<8;$j++) {
      $color_rgb[$which_circle][$j] = 0;
    }
  }

  # Now the real background in white
  $which_circle =  $number_of_background;
  $ps_color[$which_circle] = " 1 1 1 ";
  for ($j=0;$j<3;$j++) {
    $color_rgb[$which_circle][$j] = 255;
  }

  $which_circle = 0;
  $rgb[0] = $rgb[1] = $rgb[2] =0;
  $backgroundcolor = "#ffffff";
#  $background_color = "#ffffff"
}

#######################
sub defaults {

  my $label_no;

  # Name of the resulting PS-file
  $psfile = "/tmp/cd-circleprint.ps";

  # Number of label on a sheet (very incomplete use of this variable)
  $number_of_labels = 2;

  # A variable to define the backround wich is treated as an additional circle or textfield
  $number_of_background = 99;

  # which previewer
  $viewer = "/usr/X11R6/bin/gv";

  # defaults for the circles in mm
  $radius_outer = 60;
  $radius_inner = 21;

  $starting_angle = 0;

  # defaults for the radii of the text circles
  $circle_radius[0][0] = $circle_radius[1][0] = $radius_outer - 10;
  $circle_radius[0][1] = $circle_radius[1][1] = $radius_outer - 19;
  $circle_radius[0][2] = $circle_radius[1][2] = $radius_outer - 19;
  $circle_radius[0][3] = $circle_radius[1][3] = $radius_outer - 10;

  # yes, we want the the circle boundaries
  $print_circle_boundaries = 1;

  # Yes we want tickmarks as defaults
  $tickmarks = 1; 
  
  # defaults for the distance pageborder circles
  # distance between the circles
  $delta = 20;
  # distance from the bottom of the page
  $begin_from_bottom = 10;

  # distance from the left side of the page
  for ($label_no = 0; $label_no < $number_of_labels; $label_no++ ) {
    $begin_from_left[$label_no] = 40;
  }

  $x_origin = $begin_from_left[0] + $radius_outer;
  $y_origin = $begin_from_bottom + $radius_outer;

  $x_scale = 1;
  $y_scale = 1;

  $scale_x = 1;
  $scale_y = 1;

  $shift_y = 0;
  $shift_x = 0;

  $graphics_directory = "/usr/share/cd-circleprint/";
  for ( my $i=0; $i < $number_of_labels; $i++) {
    $shift_eps_x[$i] = 0;
    $shift_eps_y[$i] = 0;
    $scale_eps_x[$i] = 1;
    $scale_eps_y[$i] = 1;
    $eps_file_label[$i] = 0;
    $eps_filename[$i] = "";
  }
}

########################
sub default_attributes {
  # fontsizes
  @scalefont = qw (32 18 32 18 16 16 16 16);
  $scale = $scalefont[0]; # initial value

# This should be replaced by a routine which looks for all available fonts
# Any volunteers?
  @fontnames = qw(AvantGard AvantGard-BookOblique AvantGard-Demi AvantGard-DemiOblique Helvetica Helvetica-Oblique Helvetica-Bold Helvetica-BoldOblique Bookman-Demi Courier Palatino-Roman Times-Roman NewCenturySchlbk-Italic NewCenturySchlbk-BoldItalic NewCenturySchlbk-Italic NewCenturySchlbk-Roman);

  for (my $i=0;$i<8;$i++ ) {
    $fontfamily[$i] = "Times-Roman" ;
  }
}

########################
sub default_text {

  # The entries for the text

  $text[0][0] = "T-Shirts for";
  $text[0][1] = "unix friends";
  $text[0][2] = "";
  $text[0][3] = "www.unixstuff.de";

  $text[1][0] = "www.debian.org";
  $text[1][1] = "GNU/Linux GNU/Hurd";
  $text[1][2] = "The FREE distribution";
  $text[1][3] = "";
}

########################
sub delete_font_from_entry {

  $fontlistbox -> delete('end');
  pop(@fontnames);

}
########################
sub display_attributes {

  my $i;

  if ( $which_circle < $number_of_background) {  configure_fonts(0);  }

  $color_rgb[$which_circle][0] = $rgb[0];
  $color_rgb[$which_circle][1] = $rgb[1];
  $color_rgb[$which_circle][2] = $rgb[2];

  $ps_color[$which_circle] = " " . $rgb[0] / 255  ." " .$rgb[1] / 255 ." ".$rgb[2] / 255 ;

  $backgroundcolor = "#";

  $hexval = sprintf("%x",$color_rgb[$which_circle][0]);
  if (length($hexval) == 1) {$hexval = "0". $hexval;}
  if (length($hexval) == 0) {$hexval = "00";}

  $backgroundcolor .= $hexval;

  $hexval = sprintf("%x",$color_rgb[$which_circle][1]);
  if (length($hexval) == 1) {$hexval = "0". $hexval;}
  if (length($hexval) == 0) {$hexval = "00";}

  $backgroundcolor .= $hexval;

  $hexval = sprintf("%x",$color_rgb[$which_circle][2]);
  if (length($hexval) == 1) {$hexval = "0". $hexval;}
  if (length($hexval) == 0) {$hexval = "00";}

  $backgroundcolor .= $hexval;

  $fmw -> configure(-background => $backgroundcolor);
  $fmw -> configure(-foreground => $backgroundcolor);

  if ( $which_circle < $number_of_background) {
    if ($which_circle < 4) {
      $entry[0][$which_circle] -> configure(-foreground => $backgroundcolor);
      $entry[1][$which_circle] -> configure(-foreground => $backgroundcolor);
    }
    else {
      $textfield_entry[0][$which_circle-4] -> configure(-foreground => $backgroundcolor);
      $textfield_entry[1][$which_circle-4] -> configure(-foreground => $backgroundcolor);
    }
  }
  else {
    for ( $i=0;$i<4;$i++) {
      $entry[0][$i] -> configure(-background => $backgroundcolor);
      $entry[1][$i] -> configure(-background => $backgroundcolor);
      $textfield_entry[0][$i] -> configure(-background => $backgroundcolor);
      $textfield_entry[1][$i] -> configure(-background => $backgroundcolor);
    }
  }
}

########################
sub display_graphics_file_attributes {
  my $i;
  for ( $i = 0; $i < $number_of_labels ;$i++) {
    if ( $eps_file_label[$i]) {

      $shift_x = $shift_eps_x[$i];
      $shift_y = $shift_eps_y[$i];
      $scale_x = $scale_eps_x[$i];
      $scale_y = $scale_eps_y[$i];
    }
  }
}
########################
sub help_window {

# Very very ugly , but the pod Module can only handle STDOUT or Filehandle

  my $parser = Pod::Text->new;
  my $tmp_file_name = "/tmp/cd-circle_print.man.1";
  $parser->parse_from_file ($0, $tmp_file_name);

  my $help_window = MainWindow -> new;
  my $text = $help_window -> Scrolled("Text", -scrollbars => 'oe') -> pack;
#  $help_window -> reconfigure(-font => "r16");

  open (TMP_FILE,"<$tmp_file_name") or (return());
  while ( <TMP_FILE>) {
    $text -> insert('end',$_);
  }
  close (TMP_FILE);
# We should delete the tmp-file

  $help_window -> Button(-text => "close", 
			 -command => sub {$help_window -> destroy() if Tk::Exists($help_window)}) -> pack;
}
########################
sub info_window {
  my $info_window = MainWindow -> new;
  my $text = $info_window -> Text(-font => "r16") -> pack;

  $text -> insert('end', "cd-circleprint, a simple perl script by Matthias Kabel <matthias.kabel\@tyche.de>\n");
  $text -> insert('end', "The following people has send me patches which improved the program:\n\n" );
  $text -> insert('end', "* Dave Regan <regan\@ao.com>\n\n");
  $text -> insert('end', "cd-circleprint is published under the GNU public license\n");
  $text -> insert('end', "You should have this license in your distribution\n");
  $text -> insert('end', "If you don't, write to the Free Software Foundation, Inc., \n
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n\n");
  $text -> tagConfigure('red', -foreground => "#ff0000");
  $text -> insert('end',"May the source be with you", 'red');

  $info_window -> Button(-text => "close",
			 -command => sub {$info_window -> destroy() if Tk::Exists($info_window)}) -> pack;
}
########################
sub read_configuration {

  my @configurationfile;
  my $home = $ENV{'HOME'};
#  my $configurationfile[2] = shift;

# first we get the defaults in the program itself, so we are safe if anything goes wrong
  defaults();

# Now we start reading the different configuration files

  $configurationfile[0] = "/etc/cd-circleprint.conf";
  $configurationfile[1] = $home."/\.cd-circleprint.conf";
  $configurationfile[2] = shift if defined $_;

  foreach my $i (@configurationfile) {
    if (-f $i) {
      if (-r $i) {
	open (CONF_FILE, "< $i");
	while (<CONF_FILE>) {
	  next unless /(^\w+.*)\s+(.*$)/; # skip comments and empty lines
	  $_ =~ /(\S*?)\s+(.*)/; #(\#.*$)/; #!!!!!!!!!!!!!
	  evaluate_configuration ($1,$2);  # evaluate_configuration see below this routine!
	}
	close (CONF_FILE);
      }
      else {
	print "Oops, there was something wrong\n";
	## We need really a better routine here
      }
    }
  }

    set_graphics_attributes();
  }

########################
sub evaluate_configuration {

# much improved by Dave Regan

  my $var = $_[0];
  my $value = $_[1];
  my %symtab = map { $_, $_} @SaveVariables;

  if (defined($symtab{$var})) {
     my($eval) = qq|\$$var = "$value"|;
#    print  "Process \$var $var; \$value $value ; eval: $eval\n";
     eval $eval;
   }
}

########################
sub preview {

  # first we want a new label
  print_label();

  system "$viewer $psfile";
  return;
}

########################
sub print_circles {

  my $label_no;

  print PS_FILE "%%Page: 1 1\n\n"; # begin of page

  print PS_FILE "gsave\n";

  for ($label_no = 0;$label_no < $number_of_labels ;$label_no++) {

    print PS_FILE "$x_origin mm $y_origin mm translate \n"; # shift the origin of drawing

    # Set the clipping path
    print PS_FILE "gsave\n";
    print PS_FILE "0 0 $radius_outer mm 0 360 arc clip\n";

    # First we need the circles in the backgroundcolor
    print PS_FILE "$ps_color[$number_of_background] setrgbcolor\n";
    print PS_FILE "0 0 $radius_outer mm 0 360 arc\n";
    print PS_FILE "fill\n";
    print PS_FILE "newpath\n";

    # Then we print the graphics
    if ($eps_file_label[$label_no]) {print_graphics($eps_filename[$label_no],$label_no);}

    # After that we need the small inner circle in white
    print PS_FILE "1 1 1 setrgbcolor\n";
    print PS_FILE "0 0  $radius_inner mm 0 360 arc\n";
    print PS_FILE "fill\n";
    print PS_FILE "newpath\n";

    # Ok, now we go with the text
    # Outer upper circle or textfield
    print PS_FILE "/$fontfamily[0] reencodeISO def\n";
    print PS_FILE "/$fontfamily[0] findfont\n"; # The font we want
    print PS_FILE "$scalefont[0] scalefont setfont\n"; # scaling the font
    print PS_FILE "$ps_color[0] setrgbcolor \n";
    print PS_FILE "($text[$label_no][0])" ," ", $scalefont[0] ," ",  -$starting_angle +90," ", $circle_radius[$label_no][0]," mm OutsideCircletext\n";

    # Inner upper circle or textfield
    print PS_FILE "/$fontfamily[1] reencodeISO def\n";
    print PS_FILE "/$fontfamily[1] findfont\n";
    print PS_FILE " $scalefont[1] scalefont setfont\n";
    print PS_FILE "$ps_color[1] setrgbcolor \n";
    print PS_FILE "($text[$label_no][1])" ," ", $scalefont[1]," ",  -$starting_angle +90 , " " , $circle_radius[$label_no][1] , " mm OutsideCircletext\n";

    # Inner lower circle or textfield
    print PS_FILE "/$fontfamily[2] reencodeISO def\n";
    print PS_FILE "/$fontfamily[2] findfont\n";
    print PS_FILE " $scalefont[2] scalefont setfont\n";
    print PS_FILE "$ps_color[2] setrgbcolor \n";
    print PS_FILE "($text[$label_no][2])" ," ", $scalefont[2]," ",  -$starting_angle -90, " ", $circle_radius[$label_no][2], " mm  InsideCircletext\n";

    # Outer lower circle or textfield
    print PS_FILE "/$fontfamily[3] reencodeISO def\n";
    print PS_FILE "/$fontfamily[3] findfont\n";
    print PS_FILE " $scalefont[3] scalefont setfont\n";
    print PS_FILE "$ps_color[3] setrgbcolor \n";
    print PS_FILE "($text[$label_no][3])" ," ", $scalefont[3]," ",  -$starting_angle -90, " ", $circle_radius[$label_no][3] ," mm InsideCircletext\n";

    if ($print_circle_boundaries) {
      print PS_FILE "0 0 0 setrgbcolor\n";
      print PS_FILE "0 0  $radius_inner mm  0 360 arc\n";
      print PS_FILE "stroke\n";
      print PS_FILE "newpath\n";

      print PS_FILE "0 0 $radius_outer  mm 0 360 arc\n";
      print PS_FILE "stroke\n";
      print PS_FILE "newpath\n";
    }
    print PS_FILE "grestore\n";

    $x_origin  = -$begin_from_left[$label_no];
    $x_origin += $begin_from_left[$label_no +1] if($begin_from_left[$label_no +1]);
    $y_origin  = $delta + 2*$radius_outer;
  }
  print PS_FILE "grestore\n";
}


########################
sub print_graphics {

  my $file = shift;
  my $label_no = shift;

  get_bounding_box($file); # Very inefficient, I have to change it

  $shift_eps_x[$label_no] += $Bounding_X / 2.8346;
  $shift_eps_y[$label_no] += $Bounding_Y / 2.8346;

  $shift_eps_x[$label_no] *= $scale_eps_x[$label_no];
  $shift_eps_y[$label_no] *= $scale_eps_y[$label_no];

  print PS_FILE "gsave\n";

  print PS_FILE "$shift_eps_x[$label_no] mm $shift_eps_y[$label_no] mm translate\n";
  print PS_FILE "$scale_eps_x[$label_no] $scale_eps_y[$label_no] scale\n";

  open (EPS_FILE,"<$file");
  while ( <EPS_FILE>) {
# We should scan the graphics file for "Showpage"
    print PS_FILE $_ ;
  }
  close (EPS_FILE);

  print PS_FILE "\n\n grestore\n\n";

  $shift_eps_x[$label_no] /= $scale_eps_x[$label_no];
  $shift_eps_y[$label_no] /= $scale_eps_y[$label_no];

  $shift_eps_x[$label_no] -= $Bounding_X / 2.8346;
  $shift_eps_y[$label_no] -= $Bounding_Y / 2.8346;
}

########################
sub print_label{

  open (PS_FILE, ">$psfile") || die ("Could not open $psfile\n");

  $x_origin = $begin_from_left[0] + $radius_outer;
  $y_origin = $begin_from_bottom + $radius_outer;

  print_page_header();
  print_prolog();

  print_page_deformation();

  print_circles();
  print_textfields();
  if($tickmarks) {print_ticks();}

# now print the closing lines
  print PS_FILE "showpage\n";
  print PS_FILE "%%Trailer\n";
  print PS_FILE "%%Pages: 1\n";

  close (PS_FILE);
}

########################
sub print_page_deformation {

  print PS_FILE "%We want a deformatiopn of the page\n\n";
  print PS_FILE "$x_scale $y_scale scale\n";
  print PS_FILE "%End of deformation\n\n";
}

#####################

sub print_page_header {

print PS_FILE <<'END_OF_HEADER'
%!PS - Adobe -1.0
%%Creator: cd - label.pl
%%Title: cdlabel
%%CreationDate: Mo, 1.2.2001
%%DocumentMedia: A4 595 842 0 () ()
%%Orientation: Portrait
%%Pages: (atend)
%%DocumentFonts: Times - Roman Helvetica
%%EndComments

END_OF_HEADER

}

########################
sub print_prolog {

  print PS_FILE << 'END_OF_PROLOG'

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Reencode the font to support international characters.
%% This is taken from cdlabelgen where it is taken
%%  from GNUPlot 3.7 /term/next.trm
%% Free Software is a great thing, you can look around and use the good things
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

/reencodeISO {
  dup dup findfont dup length dict begin
	 { 1 index /FID ne { def }{ pop pop } ifelse } forall
	 /Encoding ISOLatin1Encoding def
	 currentdict end definefont
} def
	 
/ISOLatin1Encoding [ 
/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef 
/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef 
/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef 
/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef 
/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright 
/parenleft/parenright/asterisk/plus/comma/minus/period/slash 
/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon 
/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N 
/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright 
/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m 
/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde 
/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef 
/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef 
/.notdef/dotlessi/grave/acute/circumflex/tilde/macron/breve 
/dotaccent/dieresis/.notdef/ring/cedilla/.notdef/hungarumlaut 
/ogonek/caron/space/exclamdown/cent/sterling/currency/yen/brokenbar 
/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot 
/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior 
/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine 
/guillemotright/onequarter/onehalf/threequarters/questiondown 
/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla 
/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex 
/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis 
/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute 
/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis 
/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave 
/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex 
/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis 
/yacute/thorn/ydieresis
] def

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Now calculate mm and points
/mm { 72 mul 25.4 div}  def

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% A function to print the textfields properly
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Zeilenumbruch

/Wordbreak ( ) def               % Trennzeichen zwischen Worten (Leerzeichen)

% BreaklntoLines umbricht einen Text-String in Zeilen vorgegebener Laenge. Die
% Prozedur benoetigt 3 Parameter: Den Text-String, die Satzbreite und die Pro-
% zedur, die aufgerufen wird, wenn das Ende der Zeile erreicht ist. Diese Pro-
% zedur erhaelt die aktuelle Zeile als Argument auf dem Stack.
/BreakIntoLines
{ /Proc exch def
  /Linewidth exch def            % Satzbreite
  /Textstring exch def
  /Breakwidth Wordbreak          % Breite des Leerezeichens im aktuellen Font
  stringwidth pop def
  /Curwidth 0 def                % Die Breite der laufenden Zeile
  /LastWordbreak 0 def           % Index zum letzten Leerzeichen
  /Startchar 0 def               % Index zum ersten Zeichen der laufenden Zeile
  /RestOfText Textstring def     % Unverarbeiteter Rest des Textes
  
  { RestOfText
    Wordbreak search             % search sucht nach dem ersten Leerzeichen und
    { /Nextword exch def pop     % liefert, falls erfolgreich, das Wort vor dem
      /RestOfText exch def       % Leerzeichen und den restlichen Text
      /Wordwidth Nextword        % Breite des Wortes
      stringwidth pop def
      Curwidth Wordwidth add
      Linewidth gt               % Passt das Wort noch in die Zeile?
      { Textstring Startchar     % Nein. Laufende Zeile als Parameter an Proc
        LastWordbreak            % uebergeben (Zeile ausgeben) und Variablen
   Startchar sub                 % fuer naechste Zeile initialisieren.
   getinterval Proc
   /Startchar
   LastWordbreak def
   /Curwidth Wordwidth
   Breakwidth add def
      }
      { /Curwidth Curwidth       % Ja: Wort in laufende Zeile aufnehmen.
        Wordwidth add
   Breakwidth add def
      } ifelse
      /LastWordbreak
      LastWordbreak Nextword     % Index zum letzten Leerzeichen um ein Wort
      length add 1 add def       % weiterschieben
    }
    { pop exit } ifelse          % Kein blank mehr gefunden: Schleifenende.
  } loop
  /Lastchar                      % Nicht vergessen: letzte Zeile ausgeben
  Textstring length def
  Textstring Startchar
  Lastchar Startchar sub
  getinterval Proc
} def

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Center a string
/center {dup stringwidth pop 2 div neg 0 rmoveto} bind def

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Now the real thing for the circles
%
% I got this from Adobes
%  Blue Book
%  Program 10, on page 167
%  Adobe Systems Incorporated 
%  CreationDate: Thu Dec 28 13:14:59 PST 1989
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

/OutsideCircletext
{ CirctextDict begin             % This routine needs four arguments
    /Radius exch def             % radius of the circle
    /Centerangle exch def        % angle of the starting point
    /PtSize exch def             % fontsize in points
    /Str exch def                % and the text
    /XRadius Radius              % To get better results we use a little bigger radius
    PtSize 4 div add def         % for the distance between the letters
                                 %
    gsave                        % save actual Graphics State
    Centerangle Str
    FindHalfangle add rotate

    Str
    { /Charcode exch def
      ( ) dup 0 Charcode put
      Outsideplacechar
    } forall
    grestore                     % restore Graphics State
  end
} def

/InsideCircletext
{ CirctextDict begin             % 'Insidecircletext' needs the same four arguments
    /Radius exch def             % as 'Outsidecircletext'
    /Centerangle exch def
    /PtSize exch def
    /Str exch def
    /XRadius                     % To get better results we use a little smaller radius
    Radius PtSize 3 div sub      % for the distances between the lines
    def
    gsave
    Centerangle Str
    FindHalfangle sub rotate
    Str
    { /Charcode exch def
      ( ) dup 0 Charcode put
      Insideplacechar
    } forall
    grestore
  end
} def

/CirctextDict 16 dict def
CirctextDict begin
  /FindHalfangle                 % 'FindHalfangle' calculates the length of a string
  { stringwidth pop 2 div        % on the circle
    2 XRadius mul Pi mul div     % The calculation divides the length of the text
    360 mul                      % with the length of the circle. The half of the result
  } def                          % will be put on the stack

  /Outsideplacechar              % put one character on outside of the arc
  { /Char exch def               % and rotates the width of the character
    /Halfangle
    Char FindHalfangle def
    gsave
    Halfangle neg rotate         % rotate the coordinate system a half width of the character
    Radius 0 translate           %
    -90 rotate                   % senkrecht zur Kreislinie stellen.
    Char stringwidth pop         % Zeichen zentriert bzgl. des Ursprungs posit.
    2 div neg 0 moveto
    Char show
%   Char true charpath stroke    % This would show outline fonts
    grestore                     % restore the old system
    Halfangle 2 mul neg rotate   % rotate forward for one characterwidth
  } def

  /Insideplacechar               % 'Insideplacechar' works like
  { /Char exch def               % 'Outsideplacechar', but the characters are placed
    /Halfangle                   % inside of the circle and counterclockwise
    Char FindHalfangle def
    gsave
    Halfangle rotate
    Radius 0 translate
    90 rotate
    Char stringwidth pop
    2 div neg 0 moveto
    Char show
    grestore
    Halfangle 2 mul rotate
  } def

  /Pi 3.1415923 def
end

%%EndProlog

END_OF_PROLOG

}

########################
sub print_textfields {

  my $i;
  my $x_position;
  my $y_position;
  my $label_no;

  my @textwidth = qw(70 40 70 40);

  for ( $i=0; $i<4;$i++) {
    for ($label_no=0; $label_no < $number_of_labels;$label_no++  ) {
      $x_position = $begin_from_left[$label_no]  + $radius_outer + sin($i * $pi/2) *(($radius_outer -$radius_inner)/2);
      print $x_position,"\n";
      $x_position += 5 if ($i == 1);
      $x_position =  $begin_from_left[$label_no]  +5  if ($i == 3); # shift the x-position right
      print "$label_no: $x_position\n";
      $y_position = $begin_from_bottom + $radius_outer + cos($i * $pi/2)*($radius_outer + $radius_inner)/2 + ($delta+2*$radius_outer)* sin($label_no * $pi/2);

      print PS_FILE "/$fontfamily[$i+4] reencodeISO def\n";
      print PS_FILE "/$fontfamily[$i+4] findfont\n"; # The font we want
      print PS_FILE "$scalefont[$i+4] scalefont setfont\n"; # scaling the font
      print PS_FILE "$ps_color[$i+4] setrgbcolor\n"; # setting the color
      my $t = $textfield_entry[$label_no][$i] -> get ("1.0",'end'); # Get the text to print from the textfield

      if (defined $t) {
	print PS_FILE "/YLine $y_position mm def\n"; # We need this for the linebreak	
	print PS_FILE "(", $t,")\n";
	print PS_FILE "$textwidth[$i] mm \n";
	print PS_FILE "{\n$x_position mm YLine moveto\n";
	# Ok, here we are, we have to correct the current point by the half of
	# the fontsize
 	print PS_FILE "\n0 -", $scalefont[$i+4]/2 , " rmoveto\n";
	# Only the textfields above and below the hole in  the middle should be centered
	if ($i == 0 || $i ==2) {
	  print PS_FILE "center ";
	}
	print PS_FILE "show\n";
	print PS_FILE "/YLine YLine ", $scalefont[$i+4], " sub def \n }\n BreakIntoLines\n\n";
	print PS_FILE "%The next textfield\n";
      }
    }
  }
}

########################
sub print_ticks {

  my $i;
  my $label_no;

  my $x_origin = 0;
  my $y_origin = 0;

  print PS_FILE $begin_from_left[0] / 2 ," mm ", 2*$radius_outer + $delta / 2 + $begin_from_bottom , " mm moveto\n";
#  print PS_FILE $x_origin ," mm ", $y_origin ," mm moveto\n";
  print PS_FILE "gsave\n";
  print PS_FILE "/Helvetica findfont 12 scalefont setfont\n";
  print PS_FILE "90 rotate\n";
  print PS_FILE "(The tickmarks are in mm\\n";
  print PS_FILE "All complaints to matthias\@tyche.de please) center show\n newpath\n";
  print PS_FILE "grestore\n";

  print PS_FILE "gsave\n";
  print PS_FILE "/Helvetica findfont 14 scalefont setfont\n"; #Fontsize for the label
  print PS_FILE "$x_origin mm  $y_origin mm translate\n"; # origin of drawing to the middle

  print PS_FILE "newpath\n";

  # Now we want some tickmarks to calibrate our print
  $left = $begin_from_left[0] + $radius_outer;

  print PS_FILE $left   , " mm 0 mm moveto\n";
  print PS_FILE "0 mm ",$begin_from_bottom ," mm  rlineto\n"; #line to the first circle
  print PS_FILE "stroke newpath % line to the first circle\n";

  # now the tickmarks in the vertical direction beginning from bottom
  for ($i=0;$i<$begin_from_bottom;$i+= 2) {
    $tick = 3;
    if ($i % 10 == 0) {
      $tick = 10;
      print PS_FILE $left - 2*$tick , " mm ", $i ," mm  moveto ", "(", $i, ") show\n";
    }
    print PS_FILE $left  - $tick, " mm ", $i ," mm  moveto ", $left + $tick ," mm " , $i ," mm lineto\n stroke newpath\n";
  }

  # next ticks between the labels
  print PS_FILE "0 mm ", 2*$radius_outer + $begin_from_bottom , " mm translate\n";

  for ($i=0;$i<$delta;$i+= 2) {
    $tick = 3;
    if ($i % 10 == 0) {
      $tick = 10;
      print PS_FILE $left - 2*$tick, " mm ", $i ," mm moveto ", "(", $i, ") show\n";
    }
    print PS_FILE $left - $tick, " mm ", $i ," mm moveto ", $left + $tick ," mm " , $i ," mm  lineto\n stroke newpath\n";
  }


  # next ticks on the top of the page
  print PS_FILE "0 ", 2*$radius_outer + $delta , " mm translate\n";

  ### correct this with pagelength ####################
  for ($i=0;$i<3*$delta;$i+= 2) {
    $tick = 3;
    if ($i % 10 == 0) {
      $tick = 10;
      print PS_FILE $left - 2*$tick, " mm ", $i ," mm moveto ", "(", $i, ") show\n";
    }
    print PS_FILE $left - $tick, " mm ", $i ," mm moveto ", $left + $tick ," mm " , $i ," mm lineto\n stroke newpath\n";
  }

  print PS_FILE "grestore\n";

  # horizontal ticks
  # first, we have to start from the left margin
  print PS_FILE "0 ", $radius_outer + $begin_from_bottom ," mm moveto\n";
  print PS_FILE "/Helvetica findfont 12 scalefont setfont\n"; #Fontsize for the tickmarks

  $top = ($radius_outer + $begin_from_bottom);
  for (my $label_no = 0; $label_no < $number_of_labels ; $label_no++ ) {
    for ($i=0;$i<$begin_from_left[$label_no];$i+= 2) {
      $tick = 3;
      if ($i % 10 == 0) {	# every 10 mm we want a bigger tick
	$tick = 10;
	print PS_FILE  $i  , "  mm " , $top + $tick, " mm moveto \n";
	print PS_FILE  "90 rotate ($i) show\n";
	print PS_FILE  "-90 rotate\n";
      }
      print PS_FILE $i, " mm ", $top - $tick," mm  moveto ", $i ," mm " ,$top + $tick ,"  mm lineto\n stroke newpath\n";
    }
    print PS_FILE "0 mm " , 2*$radius_outer + $delta , " mm translate\n";
  }
}

########################
sub evaluate_shortcuts() {

  my @shortcuts = shift;
#  print "ARGS: @\_\n";

}
########################
sub get_bounding_box() {

  my $eps_file = shift;

  if ( open (EPS_FILE ,"<$eps_file") ) {
    while ( <EPS_FILE>) {
      if ( $_ =~ /(%%BoundingBox: )(\d*)( )(\d*)( )(\d*)( )(\d*)/) {
	$Bounding_X = ($2 - $6) / 2;
	$Bounding_Y = ($4 - $8) / 2;
	last;		#!# exit the while loop here
      }
    }
    close ($eps_file);
  }
  else {
    warning_window("There seems no bounding box in $eps_file\nHope the best\n");
  }
}

########################
sub get_eps_file {
  my $FSref;
  my $dummy;
  my $i;

 for ( $i=0;$i < $number_of_labels;$i++) {
   $dummy = $eps_filename[$i] if $eps_file_label[$i];
 }

# set the filename if defined as default !!!!!!!!!!!
  $FSref = $mw -> FileSelect(-directory => $graphics_directory,
			     -defaultextension => "eps",
			     -initialfile => $dummy);

  $graphics_file = $FSref -> Show;

  if ( defined $graphics_file) {
    for ( $i=0;$i < $number_of_labels;$i++) {
      if ($eps_file_label[$i]) {
	$eps_filename[$i] = $graphics_file;
	$eps_file_entry[$i] -> configure(-textvariable => \$graphics_file);
      }
    }
  }
  return $graphics_file;
}

########################
sub get_fontattributes {

  my $fwb; #Frame for buttons
  my $fw; #Frame
  my $flco;

  $fmw = MainWindow -> new;

  $fmw -> title("FONTS, size and colours");

# One frame for Ok and Close-button
  $fwb = $fmw -> Frame(-relief => 'raised', -bd => 2) -> pack(-side => 'bottom',
						      -fill => 'both',
						      -anchor => 's',
						      -expand => '1');

# Now we want a frame for the size and the radiobuttons
  $fw = $fmw -> Frame(-relief => 'raised', -bd => 2) -> pack(-side => 'left',
						      -fill => 'both',
						      -anchor => 'e',
						      -expand => '1');

# This frame ois divided in two frames

  $fwc = $fw -> Frame() -> pack(-side => 'left',
				-fill => 'both');

  $fwt = $fw -> Frame() -> pack(-side => 'left',
				-fill => 'both');

  $fwc -> Radiobutton(-text => "Outer circle up",
		     -value => 0,
		     -variable => \$which_circle,
		     -command => sub{set_fontattributes()}) ->pack(-expand => 'x',
								    -anchor => 'w');
  $fwc -> Radiobutton(-text => "Inner circle up",
		     -value => 1,
		     -variable => \$which_circle,
		     -command => sub{set_fontattributes()}) ->pack(-expand => 'x',
								   -anchor => 'w',);
  $fwc -> Radiobutton(-text => "Inner circle down",
		     -value => 2,
		     -variable => \$which_circle,
		     -command => sub{set_fontattributes()}) ->pack(-expand => 'x',
								    -anchor => 'w');
  $fwc -> Radiobutton(-text => "Outer circle down",
		     -value => 3,
		     -variable => \$which_circle,
		     -command => sub{set_fontattributes()}) ->pack(-expand => 'x',
								    -anchor => 'w');


  $fwt -> Radiobutton(-text => "Top textfield",
		     -value => 4,
		     -variable => \$which_circle,
		     -command => sub{set_fontattributes()}) ->pack(-expand => 'x',
								    -anchor => 'w');
  $fwt -> Radiobutton(-text => "Left textfield",
		     -value => 5,
		     -variable => \$which_circle,
		     -command => sub{set_fontattributes()}) ->pack(-expand => 'x',
								   -anchor => 'w',);
  $fwt -> Radiobutton(-text => "right textfield",
		     -value => 6,
		     -variable => \$which_circle,
		     -command => sub{set_fontattributes()}) ->pack(-expand => 'x',
								    -anchor => 'w');
  $fwt -> Radiobutton(-text => "Bottom textfield",
		     -value => 7,
		     -variable => \$which_circle,
		     -command => sub{set_fontattributes()}) ->pack(-expand => 'x',
								    -anchor => 'w');


  $fw -> Radiobutton(-text => "Background",
		     -value => $number_of_background,
		     -variable => \$which_circle,
		     -command => sub{set_background()}) ->pack(-expand => 'x',
							       -anchor => 'w');
  $fw -> Scale(-from => 8,
	       -to => 44,
	       -orient => 'horizontal',
	       -variable => \$scale,
	       -command => sub{display_attributes() } ) -> pack(-side => 'right',
									-expand => 'x') ;


############################################################
# Now stop the frame an put the close-button in the window
############################################################

  $fwb -> Button(-text => "close",
		 -command => sub{$fmw -> destroy() if Tk::Exists($fmw)}) -> pack;

############################################################
# An other frame for the fontlist
############################################################

  $flb = $fmw -> Frame(-relief => 'raised', -bd => 2) -> pack(-side => 'left',
							      -fill => 'x',
							      -anchor => 'e',
							      -expand => '1');

  $fontlistbox = $flb -> Scrolled("Listbox", -scrollbars => "se", -selectmode => "single") -> pack();

############################################################
# we should have these fonts with ghostscript
# feel free to write a subroutine to fill the listbox with fonts that real exist on the local machine
############################################################

  foreach $i  ( @fontnames) {
    $fontlistbox -> insert('end', $i);
  }

  $fontlistbox -> bind('<Button-1>',
		       sub{$fontfamily[$which_circle] =  $fontnames[$fontlistbox -> curselection];
			   set_fontattributes()
			 }
		      );

  $fontlistbox -> bind('<Button-3>',
		       sub{$fontlistbox -> delete($fontlistbox -> curselection);});

  $flb -> Button(-text => "Delete selected",
		-command => sub{$fontlistbox -> delete($fontlistbox -> curselection)}) -> pack(-side => 'top');

  $flb -> Label(-text => "Additional fonts:") -> pack();
  $fontentry = $flb -> Entry(-background => "#ffffff") -> pack();
  $flb -> Button(-text => "Add",
		 -command => \&add_font_from_entry) -> pack(-side => 'left');

#####################################
# Next we want a frame for colors
#####################################

$fco = $fmw -> Frame(-relief => 'raised', -bd => 2) -> pack(-side => 'left',
							    -fill => 'x',
							    -anchor => 'e',
							    -expand => '1');

$fco -> bind("<ButtonRelease>",\&display_attributes($which_circle));

$fco ->  Scale(-label => "red",
	       -variable => \$rgb[0],
	       -resolution => 1,
	       -command => sub{display_attributes()},
	       -from => 255, -to => 0) -> pack(-side => 'left');
$fco ->  Scale(-label => "green",
	       -variable => \$rgb[1],
	       -resolution => 1,
	       -command => sub{display_attributes()},
	       -from => 255, -to => 0) -> pack(-side => 'left');
$fco ->  Scale(-label => "blue",
	       -variable => \$rgb[2],
	       -resolution => 1,
	       -command => sub{display_attributes()},
	       -from => 255, -to => 0) -> pack(-side => 'left');
}
########################
sub get_graphics {
  my $fmw;
  my $fwb; #Frame for labelbuttons
  my $fwcb; #Frame for close button
  my $fwf; #Frame for the files
  my $fwg; #Frame for graphics-place buttons
  my $fw; #Frame for the radiobuttons
  my $i;

  $fmw = MainWindow -> new;

  $fmw -> title("Graphics files");

# One frame for the labels
  $fwb = $fmw -> Frame(-relief => 'raised', -bd => 2) -> pack(-side => 'top',
							      -fill => 'both',
							      -anchor => 'n',
							      -expand => '1');

# One more frame for the Files
  $fwf = $fmw -> Frame(-relief => 'raised', -bd => 2) -> pack(-side => 'top',
							       -fill => 'both');

# One more for shifting
  $fwshift = $fmw -> Frame(-relief => 'raised', -bd => 2) -> pack(-side => 'top',
							       -fill => 'both');
# One more for scaling
  $fwscale = $fmw -> Frame(-relief => 'raised', -bd => 2) -> pack(-side => 'top',
							       -fill => 'both');

# One frame for Ok and Close-button
  $fwcb = $fmw -> Frame(-relief => 'raised', -bd => 2) -> pack(-side => 'top',
							       -fill => 'both',
							       -expand => '1');

  $fwb -> Checkbutton(-text => "Upper label",
		     -variable => \$eps_file_label[1],
		     -command => sub{set_graphics_attributes()}) -> pack(-side => 'right',
						       -expand => 'x',
						       -anchor => 'w');
  $fwb -> Checkbutton(-text => "Lower label",
		     -variable => \$eps_file_label[0],
		     -command => sub{set_graphics_attributes()}) -> pack(-side => 'right',
						       -expand => 'x',
						       -anchor => 'w',);

# $file_dialog_button
#  $eps_file_entry = $fwf -> Entry(-text => "EPS-File",
#				  -textvariable => \$graphics_file,
#				  -background => "#ffffff") -> pack();

  for ($i=0;$i < $number_of_labels; $i++) {
    $eps_file_entry[$i] = $fwf -> Entry(-text => "EPS-File $i",
					-textvariable => \$eps_filename[$i],
					-background => "#ffffff") -> pack(-side => 'bottom');
  }

  $fwf -> Button(-text => "browse",
		 -command => sub{get_eps_file()}) -> pack();

  $fwshift -> Scale(-label => "Offset X",
		    -from => -$radius_outer, -to => $radius_outer,
		    -orient => "horizontal",
		    -command => sub{set_graphics_attributes()},
		    -variable => \$shift_x) -> pack(-side => "left");

  $fwshift -> Scale(-label => "Offset Y",
		    -from => $radius_outer, -to => -$radius_outer,
		    -orient => "vertical",
		    -command => sub{set_graphics_attributes()},
		    -variable => \$shift_y) -> pack(-side => "right");

  $fwscale -> Scale(-label => "Scale X",
		    -from => 0, -to => 1,
		    -resolution => "0.01",
		    -orient => "horizontal",
		    -command => sub{set_graphics_attributes()},
		    -variable => \$scale_x) -> pack(-side => "left");

  $fwscale -> Scale(-label => "Scale Y",
		    -from => 1, -to => 0,
		    -resolution => "0.01",
		    -orient => "vertical",
		    -command => sub{set_graphics_attributes()},
		    -variable => \$scale_y) -> pack(-side => "right");

  $fwcb -> Button(-text => "close",
		  -command => sub{$fmw -> destroy() if Tk::Exists($fmw)}) -> pack(-side => 'bottom');
}

########################
sub get_previewer {
  my $dummy;
  my $FSref;

  $FSref = $mw -> FileSelect(-directory => "/usr/bin");
  $dummy = $FSref -> Show;

  $viewer = $dummy if defined $dummy;
#We should verify that the chosen file is executable !!!!!!!!!!!
}
########################
sub get_starting_angle {

  my $starting_angle_window;

  $starting_angle_window = MainWindow -> new;

  $starting_angle_window -> Scale(-label => "Angle to middle of the text",
				  -from => -90, -to => 90,
				  -resolution => "1",
				  -orient => "horizontal",
#				  -command => sub{set_graphics_attributes()},
				  -variable => \$starting_angle) -> pack(-side => "top");

  $starting_angle_window -> Button(-text => "Ok",
				   -command => sub {$starting_angle_window -> destroy()
						      if Tk::Exists($starting_angle_window)}) -> pack(-side => "bottom");
}
########################
sub save_ps_file {

  my $FSref;
  my $home = $ENV{'HOME'};

  $FSref = $mw -> FileSelect(-directory => $home);
  $psfile = $FSref -> Show;

  print_label;
}

########################
sub set_background {

  $rgb[0] = $color_rgb[99][0];
  $rgb[1] = $color_rgb[99][1];
  $rgb[2] = $color_rgb[99][2];
  display_attributes();
}
########################
sub set_circle_radius {

if (! Exists($crw)) {
    my $crw = $mw -> Toplevel();
    $crw -> title("Radii");
    $crw -> Button(-text => "OK",
		   -command => sub {$crw -> withdraw}) -> pack(-side => 'bottom');
    $crw -> Label(-text => "There are many labels. Some have a different radius for the inner circle") -> pack(-side => 'top');
    #$crw -> Label(-text => "Radius of the inner circle [mm]}") -> pack(-side => 'top');

    $tf = $crw -> Frame(-label => "Radius of the inner circle [mm]", -borderwidth => "5") -> pack(-side => 'top');
    $tf -> Scale(-orient => 'horizontal',
		  -variable => \$radius_inner,
		  -from => 0, -to => 50,) -> pack(-side => 'left');

    $bf = $crw -> Frame(-label => "Radius of the inner text-circles [mm]") -> pack(-side => 'bottom');
    # Now the radii for the text circles

    my @side = qw (bottom right);

    for (my $j=0; $j<2 ; $j++) {
      $lf[$j] = $bf -> Frame(-label => "Circle $j", -borderwidth => "5", -relief => 'groove') -> pack(-side => 'left');
      for ( my $i=0; $i<4 ; $i++) {
	$lf[$j] -> Scale(-orient => 'horizontal',
		     -variable => \$circle_radius[$j][$i],
		     -from => $radius_inner, -to => $radius_outer,) -> pack(-side => 'top');
      }
    }
  }
  else {
    $crw -> deiconify();
    $crw -> raise();
  }
}
########################
sub set_fontattributes {

    $scale = $scalefont[$which_circle];

    $rgb[0] = $color_rgb[$which_circle][0];
    $rgb[1] = $color_rgb[$which_circle][1];
    $rgb[2] = $color_rgb[$which_circle][2];

# display the right entry in the fontlistbox
    foreach (0 .. $#fontnames ) {
      if ( $fontnames[$_] =~ /$fontfamily[$which_circle]/) {
	$fontlistbox -> selectionClear(0, "end");
	$fontlistbox -> selectionSet($_);
	$fontlistbox -> see($_);
      }
    }
    display_attributes();
}
########################
sub set_graphics_attributes {

  my $i;
  for ( $i = 0; $i<$number_of_labels;$i++) {
    if ( $eps_file_label[$i] ) {
      $scale_eps_x[$i] = $scale_x;
      $scale_eps_y[$i] = $scale_y;

      $shift_eps_x[$i] = $shift_x;
      $shift_eps_y[$i] = $shift_y;

      $graphics_file = $eps_filename[$i];
      $eps_file_entry[$i] -> configure(-textvariable => \$eps_filename[$i]) if defined $eps_file_entry[$i];
    }
  }
  display_graphics_file_attributes();
}

########################
sub set_page_scaling {

  if (! Exists($spw)) {
    my $spw = $mw -> Toplevel();
    $spw -> title("Scale the whole page");
    $spw -> Button(-text => "OK",
		   -command => sub {$spw -> withdraw}) -> pack(-side => 'bottom');
    $spw -> Label(-text => "Some printers don\'t print exact circles,\n so you can scale the page") -> pack; 
    $spw -> Scale(-label => "horizontal scale",
		  -orient => 'horizontal',
		  -resolution => 0.01,
		  -variable => \$x_scale,
		  -from => .9, -to => 1.1,) -> pack(-side => 'left');
    $spw -> Scale(-label => "vertical scale",
		  -variable => \$y_scale,
		  -resolution => 0.01,
		  -from => 1.1, -to => .9 ) -> pack;
  }
  else {
    $spw -> deiconify();
    $spw -> raise();
  }

}

########################
sub set_distances {

  if (! Exists($spw)) {
    my $spw = $mw -> Toplevel();
    $spw -> title("Change some distance to fit the sheet");
    $spw -> Button(-text => "OK",
		   -command => sub {$spw -> withdraw}) -> pack(-side => 'bottom');
    $spw -> Label(-text => "Here you can move the circle around the page.\nUse the tickmarks\n") -> pack;

    my $fwt = $spw -> Frame(-relief => 'sunken') -> pack(-side => 'top');

    for (my $label_no = 0;$label_no < $number_of_labels; $label_no++ ) {
      $fwt -> Scale(-label => "move circle $label_no horizontal",
		    -orient => 'horizontal',
		    -length => 250,
		    -resolution => 0.1,
		    -variable => \$begin_from_left[$label_no],
		    -from => 0, -to => 250,) -> pack(-side => 'bottom');
    }

# We want a frame for the scales
    my $fw = $spw -> Frame(-label => "vertical scales") -> pack(-side => 'bottom');

    $fw -> Scale(-label => "start from bottom",
		 -variable => \$begin_from_bottom,
		 -resolution => 0.1,
		 -from => 200, -to => -50 ) -> pack(-side => 'left');
    $fw -> Scale(-label => "delta between the circles",
		 -variable => \$delta,
		 -resolution => 0.1,
		 -from => 100, -to => 0 ) -> pack(-side => 'right');
  }
  else {
    $spw -> deiconify();
    $spw -> raise();
  }
}

########################
sub warning_window {

  my $message = shift;
  my $warning_main_window = MainWindow -> new;

  my $text = $warning_main_window -> Label(-text => $message,
					  -background => '#ff0000') -> pack;

  $warning_main_window -> Button(-text => "Ok",
				 -command => sub {$warning_main_window -> destroy() 
						    if Tk::Exists($warning_main_window)}) -> pack;

}
########################
sub write_configuration {

  my $home = $ENV{'HOME'};
  my $date = localtime;
  my @dummy;

  for (my $i = 0; $i < $number_of_labels; $i++) {
    for (my $j = 0; $j < 4; $j++) {
       $dummy[$i][$j] = $textfield_entry[$i][$j] -> get("1.0",'end');
       chop $dummy[$i][$j];
    }
  }

  open (CONF_FILE , "> $home/.cd-circleprint.conf") or print  ("I'm sorry, I wasn't able to write the configuration.");

  print CONF_FILE "#Configuration for cd-circleprint\n";
  print CONF_FILE "#written  $date \n\n";

  # Write all of the variables we know about from the SaveVariables routine
  my($sym, $val);
  foreach $sym (@SaveVariables) {
      my($eval) = "\$val = \$$sym";
#      print  "Process $sym $eval\n\n";
      eval $eval;
      print CONF_FILE "$sym $val\n" if (defined($val));
  }

  close (CONF_FILE);
}

########################
sub dummy {

  my $dw;
  my $text;

  $dw = MaindWindow -> new;
  $text = $dw -> Scrolled("Text", -scrollbars => 'oe') -> pack;
  $text -> insert('end',"Sorry this function is not implemented yet.");
  $dw -> Button(-text => "close",
			 -command => sub {$dw -> destroy() if Tk::Exists($dw)}) -> pack;
}

########################################
#
# Documentation
# Needs much more
# Any english speaking volunteers?
#
#######################################


=pod MANUAL PAGE

=head1 NAME

cd-circleprint - create a nice round shaped label for a CD

THIS MANUAL PAGE IS VERY INCOMPLETE

Please play around with the program to see all options

=head1 SYNOPSIS

cd-circleprint FILE

You can specify an alternate configurationfile in the commandline

=head1 DESCRIPTION

cd-circleprint prints two round shaped labels for CDs. It uses up to four lines of text for each
label. This text is printed in arcs so the text can be much longer than in straight lines.

The output is in postscript, this should work on most systems.

You can choose the font the size and the color of the text for each line separately. And you
can choose the background color of the label itself. If you wish more complicated backgrounds
or color effects you can save a label and use in any graphic program which can read
postscript. (I suggest "The Gimp")

=head1 LAYOUT

All layout is done in postscript, this should work on most systems.

The resulting layout are two cd-labels on one sheet of paper. In each label there are two
convex and two concave lines of text. If you have a very long line of text, you can use only
one line and make it longer, there are no limits for the length of text.
But after 360 degrees the text is overlapping with the beginning.

Furthermore there are four textfields in each label which are simply straight forward.

The colors are done in the RGB-model of Postscript, you can choose them for each line and 
the background of the label independently.

You can move the circles around the sheet to fit them on the most types of label-sheets.

You can also squeeze or stretch the whole thing to correct small errors of your printer.

=head1 USING

After starting the program you can see sixteen text-entry fields divided in two blocks. 
The upper block is for the textfields the lower block for the arcs.

Each label has four textfields and four arcs.
The first two lines are for the upper arcs on the label and the last two for the lower arcs.

Write your text in the fields (support for a cddb is on the TODO list)
and press the button "label" or press Control-l in the menu on top of the window. This button creates a file
/tmp/cd-circleprint.ps which can be previewed with an postscript viewer. There is a button to start
your favorite previewer or you can press Control-p.

Font attributes and colors can changed interactively with the menu.

=head2 Shortcuts
Control-l: write the label in /tmp
Control-p: preview the label
Control-q: quit
Control-s: save the configuration

=item B<Label-Options>

=item I<Font-attributes>
Here you can change fontfamily, fontsize, font-color and the backgroundcolor interactively, all
changes should take effect immediately in the text entry fields.

Be carefully, perl-tk uses the nearest match for the font maybe the labels look different on your printer.

=item I<Radii>
There are many types of CD-labels, so here you are able to correct the size of the inner circle.

Additional, you can change the radius for all four text-lines.

=item I<Size>
Some printers are not working correctly with circles and produce a ellipse. So you can squeeze or stretch
the whole page to get perfect circles with your printer.

=item I<tickmarks>
There are many cd-label sheets on the market, so you can move the circles around the page. To make this
easier, you can print some tickmarks on the page to measure the distances.
If you have the correct values, you don't need this tickmarks any more can save some ink.

=item I<distances>
You can move the circles around the page with this menu.

=item I<graphics>
You can put some graphics on the label. This graphics has currently to be in eps-format.
Be careful, I had problems with some eps-graphics created by The Gimp, which had a "showpage" in it.
After deleting this line everything worked fine. I will look if this is a feature or a bug.

I thought about automatic scaling, but the program would
have to know the real size of the visible part of the graphic but it knows only the bounding box.

The scaling and shifting should be self-explanatory. The programs get the bounding box of the eps and 
puts the graphics in the middle of the label.

=head1 CONFIGURATION

You can save your configuration in a file in your $HOME or ask your sysadmin to create a global configuration-file.

Not all options are stored now, but I'm working on it.

=head1 FILES

There is a global configuration file /etc/cd-circleprint.conf and a local configuration file 
$HOME/.cd-circleprint.conf

You can specify an other configuration file on the commandline, than the default configuration files are ignored.
For the format of the configuration files take look at them.
comments start with a # and blank lines are ignored.

The program sets its internal default values, looks for the global configuration and then
for the local configuration file.

=head1 BUGS

There are sure a many bugs and much more ugly code but it works.
Please fix them and send me a patch.
Any native english speaker who wants to correct the bad English of this man-page would be welcome too.
Thanks

=head1 AUTHORS

cd-circleprint is written and maintained by Matthias Kabel <matthias.kabel@tyche.de>

You can find the latest version on http://cd-circle-print.sourceforge.net
The program is licensed under the GNU Public License version 2 or higher

Thanks to sourceforge.net for hosting free software

=cut

# END of File

