#!/usr/bin/perl -w

package Tile::OneRekursion;

use Tile::Prototile;
use Data::Dumper;
use strict;

# Constant color number to create user defined colors, given in hex code
use constant COLOR_CONST => 32;
my $runnedRecursions = 0;

# this class takes no constructor with parameters
sub new
{
  my $classname = shift;  # we know our class name
  my $class = ref($classname) || $classname; # now the constructor can be use as an constructor or an object method
  
  # anonymous object hash
  my $self  = {};
        $self->{NAME}   = undef; # name is used to identify the rekursion step NAME = rekursion_step_12
	$self->{INFLATION_FAKTOR}	 = undef;#
        $self->{NUMBER_OF_PROTOTILES}    = 0; # null prototiles read at the beginnning
        $self->{NAMES_OF_PROTOTILES}     = []; # anonymous hash holds the prototile names
	$self->{PROTOTILES}              = []; # the names of the prototiles are used as hashkey
	$self->{USERDEFCOLORS}		 = (); # empty list wich contains the user defined colors
	$self->{COMMENT}		 = ""; # comment for the Xfig file
	$self->{AUTHOR}			 = ""; # author who created the xfig file
	$self->{USEDFILE}		 = "UNKOWN"; # wich files were used
	$self->{OUTPUT}			 = ""; # name of the outputfile
  bless($self,$class);    # bless object
  return $self;           # return this object
}


# does the recursions on all prototiles
sub doRekursionOnAllProtos(){
	my $self = shift;
	my @saat_list; #refs to all created new saat infos of new rekursion step
	my $objToWrite;
	$runnedRecursions++;
	
	# process all Prototiles
	foreach my $proto_ident (@{$self->{PROTOTILES}}){
	
		#do the rekursion
		push(@saat_list,$proto_ident->{REF_TO_OBJ}->doRekursion());
	}
	
	
	#add new saat infos to prototile objects
	foreach my $saatListItem (shift(@saat_list)){
		
		#process new saat infos wich were created by one tile
		foreach my $saatInfo (@{$saatListItem}){
			
			# write saat infos to the accordant tile
			$objToWrite = $self->getPrototileByName(("P ".$saatInfo->{PROTOTILE_NR}));
			
			# security test
			#
			# is in $objToWrite a hash reference to a prototile object ?
			# if not, exit the programm, because the family file isnt
			# valid !
			if($objToWrite =~ /Tile::Prototile=HASH/){
				#print ("Object to Write: ".$objToWrite."\n");
				$objToWrite->addSaatInfo($saatInfo->{DEG},$saatInfo->{X1},$saatInfo->{Y1});
			}
			else{
				print ("Quitting Tilewizard!\n");
				die "It seems that your family file is not valid!\n";
			}
		}
	}
	
	# delete all old infos
	#@saat_list = ();
	# process all Prototiles
	foreach my $proto_ident (@{$self->{PROTOTILES}}){
	
		$proto_ident->{REF_TO_OBJ}->deleteNewSaat();
	}
	
}

# translates all informations to a xfig file
sub translateAllProtos(){
	my $self = shift;
	
	my $outputhandle = "Tilewizard_Output.fig";
	if($self->{OUTPUT} ne "none" && $self->{OUTPUT} ne "" ){
		$outputhandle = $self->{OUTPUT}.".fig";
	}
	
	# write information to xfig file
	unless (open Xfig_dateihandle, ">".$outputhandle){
		die "Unable to attach information to output file: $!";
	}
	 
	#write header of Xfig file 
	&writeXfigHeader($self);
	
	close Xfig_dateihandle;
	
	# process all Prototiles
	foreach my $proto_ident (@{$self->{PROTOTILES}}){
		$proto_ident->{REF_TO_OBJ}->translateToVector();
	}	
}

# writes xfig header
sub writeXfigHeader(){
	my ($self) = @_;
	# standard dina4
	my $txt_usedfiles = "";
	my $txt_author = "#Picture-Author: ".$self->{AUTHOR}."\n";
	my $txt_usedFile = "#Used family file: ".$self->{USEDFILE}."\n";
	my $txt_recs = "#Recursion depth: ".$runnedRecursions."\n";
	my $txt_picture = "#Comment: ".$self->{COMMENT}."\n";
	my $txt_developer = "#This picture was generated automatically.\n#Programm used: Tilewizard\n#Author: Jan Pieniak\n#E-Mail: jan.pieniak\@gmx.de\n";
	print Xfig_dateihandle ("#FIG 3.2\nPortrait\nCenter\nMetric\nA4\n100.00\nSingle\n-2\n".$txt_developer.$txt_author.$txt_usedFile.$txt_recs.$txt_picture."1200 2\n");
	
	
	# now attach user defined colors to xfig file
	my $cNr = COLOR_CONST;
	
	foreach my $c (@{$self->{USERDEFCOLORS}}){
		print Xfig_dateihandle ("0 ".$cNr." ".$c."\n");
		$cNr++;
	}
}

# creates a new prototile obj
sub createNewPrototile(){
	my $self = shift;
	my($protoName) = @_;
	
	# there is a new prototile, then add its name to the proto name list
	push(@{$self->{NAMES_OF_PROTOTILES}}, $protoName);
	
	# anonymous hash to identify the prototile obj`s
	my $proto_identifier = {
		PROTO_NAME => undef,
		REF_TO_OBJ => undef,
		};
	
	# use the protoname to find the proto obj
	$proto_identifier->{PROTO_NAME} = $protoName;
	# create new Prototile obj and name it
	$proto_identifier->{REF_TO_OBJ} = Tile::Prototile->new();
	$proto_identifier->{REF_TO_OBJ}->name("".$protoName);
	$proto_identifier->{REF_TO_OBJ}->{OUTPUT} = $self->{OUTPUT};
	$proto_identifier->{REF_TO_OBJ}->{INFLATION_FAKTOR} = $self->{INFLATION_FAKTOR};
	# add new prototile obj to list prototile obj`s
	push(@{$self->{PROTOTILES}},$proto_identifier);
	
}

# returns a prototile, searched by its name
sub getPrototileByName(){
	my $self = shift;
	my ($protoName) = @_;
	
	# search in prototile list for prototile name
	foreach my $key (@{$self->{PROTOTILES}}){
  		if($key->{PROTO_NAME} =~ $protoName){
			return ($key->{REF_TO_OBJ});
		}
	}
	
	#returns false if prototile does not exists or was not found
	return 0;	
}

# returns the names of all prototiles
sub prototileNames(){
	my $self = shift;
	my ($protoName) = @_;
	
	# do if parameters are given
	if (@_) { 
		push(@{$self->{NAMES_OF_PROTOTILES}}, $protoName);
	}
	
	#return ref to list
	return $self->{NAMES_OF_PROTOTILES};
}

# checks if a given prototile exists
sub searchPrototile(){
	my ($hash_ref,$string) = @_;
	
	foreach my $key (keys %{$hash_ref}){
  		if($key =~ $string){
   			print("Found Key in Hash");
		}
	}
}

# adds a new user defined color to the user defined color list and
# returns the colornumber
sub addUserDefColor(){
	my $self = shift;
	my ($hexColor) = @_;
	
	push(@{$self->{USERDEFCOLORS}},$hexColor);
	return (@{$self->{USERDEFCOLORS}} + COLOR_CONST - 1);
}


# prints the informations wich this object holds
sub printObjectInfos(){
	my $self = shift;
	print("------------Object Name: ".$self->{NAME}." ---------------\n");
	print("Number of Prototiles: ".$self->{NUMBER_OF_PROTOTILES}."\n");
	print("Inflation factor: ".$self->{INFLATION_FAKTOR}."\n");
	print("Prototile Names: ");
	&printList($self->prototileNames());
	
	print("\n\n");
	
	#print all prototile ojbs
	foreach(@{$self->{PROTOTILES}}){
		$_->{REF_TO_OBJ}->printObjectInfos();
	}
}

# print a list
sub printList(){
	my ($list) = @_;
	
	foreach(@{$list}){
		print($_.", "); 
	}
	print("\n");	
}

# return true everytime, becaus this is an perl object
1;