#!/usr/bin/perl -Imodules

#use Cluster::Clustering;
use Time::HiRes;

my @R				= ();
my @SW				= ();
my @CON				= ();
my @DOUBLE			= ();
my @CLUSTERRESULTS	= ();
my $CLUSTERDESC		= {};
my $CLUSTERTITLE	= {};
my $HashRefDoubleItems = {};
my $temp;
my $count	= 0;
my $wordcount = 0;
my $ResultCountTitle = 0;
my $ResultCountDesc	 = 0;


# kommt später aus der config:

my $MaxCountClusterTitle		= 5;
my $MaxCountClusterDesc			= 5;
my $IgnoreResultsShorterThan	= 4;



open(RH, "<CLUSTER.txt");
	@CON = <RH>;
close RH;

open(SW, "<stopwords.txt");
	@SW = <SW>;
close SW;

my $s1 = Time::HiRes::time();

foreach my $line ( @CON ) {
	my ( $url, $title, $desc, $engine ) = split('#\t#', $line);
	$ResultHashRefUrl{$count}		= $url;
	$ResultHashRefTitle{$count}		= $title;
	$ResultHashRefDesc{$count}		= $desc;
	$ResultHashRefEngine{$count}	= $engine;
	$ResultHashRefBoost{$count}		= "1.0";
	$count++;
};


# für alle descriptions, splitte die einzelnen wörter auf und speichere sie in einer Hashreferenz, die zeiger auf die entsprechende
# arrayreferenz mit den einzelnen wörtern der description enthält

for ( my $i=0; $i<=$count; $i++ ) {
	
	my @R = split(' ', $ResultHashRefDesc{$i}); 
	my @Q = split(' ', $ResultHashRefTitle{$i}); 

	# hier folgt der algoritmus zum entfernene der stopwörter aus der description des jeweiligen eintrages
	foreach my $sw ( @SW ) {
		chomp($sw);
		foreach my $r ( @R ) {
			next if ( $r eq ' ' );	# ignoriere leerzeichen 
			if ( lc($sw) eq lc($r) ) {
				undef $r;
			};
		};
	};

	foreach my $sw ( @SW ) {
		chomp($sw);
		foreach my $q ( @Q ) {
			next if ( $q eq ' ' );
			if ( lc($sw) eq lc($q) ) {
				undef $r; #$r = "";
			};
		};
	};

	$CLUSTERDESC{$i}  = \@R;
	$CLUSTERTITLE{$i} = \@Q;

};


# fische die doppelten Einträge herraus
# Wichtig; bei $i=1 anfangen zu zählen und bei $j=0 !!!!!!!

for ( my $i=1 ; $i<=$count ; $i++ ) {
	for ( my $j=0 ; $j<=$count ; $j++ ) {
		next if ( $i == $j );
		if ( $ResultHashRefUrl{$i} eq $ResultHashRefUrl{$j} ) {
			push(@DOUBLE, "$i $j");
		};
	};
};


# für jeden doppelten eintrag lösche diesen, merke dir aber in welcher suchmaschine der eintrag doppelt vorkam

foreach my $double ( @DOUBLE ) {
	my ( $i, $j ) = split(' ', $double );
	
	chomp($ResultHashRefEngine{$i});
	chomp($ResultHashRefEngine{$j});

	if ( $ResultHashRefEngine{$i} eq '' ) {
		next if ( $ResultHashRefEngine{$j} eq '' );
		$temp = "$ResultHashRefEngine{$j}";
	} elsif ( $ResultHashRefEngine{$j} eq '' ) {
		next if ( $ResultHashRefEngine{$i} eq '' );
		$temp = "$ResultHashRefEngine{$i}";
	} elsif ( $ResultHashRefEngine{$i} ne '' && $ResultHashRefEngine{$j} ne ''  ) {
		$temp = "$ResultHashRefEngine{$i}" . " " . "$ResultHashRefEngine{$j}";
	};

	delete $ResultHashRefEngine{$i};
	delete $ResultHashRefUrl{$j};
	delete $ResultHashRefTitle{$j};
	delete $ResultHashRefDesc{$j};
	delete $ResultHashRefEngine{$j};
	delete $ResultHashRefBoost{$j};
	
	$ResultHashRefEngine{$i} = $temp;
	$ResultHashRefBoost{$i} = "1.0";

	# Algorithmus zur Bestimmung des Neuen Boost Faktors
	my @COUNTENGINES = split(' ', $ResultHashRefEngine{$i});
	$ResultHashRefBoost{$i} = ( $ResultHashRefBoost{$i} ) + (( $#COUNTENGINES + 1 ) / 10 );
	
};


# Alle leerzeichen entfernen
for ( my $i=1 ; $i<=$count ; $i++ ) {
	chomp($ResultHashRefUrl{$i});
	chomp($ResultHashRefTitle{$i});
	chomp($ResultHashRefDesc{$i});
	chomp($ResultHashRefEngine{$i});
	chomp($ResultHashRefBoost{$i});
};


#	Vergleich von 2 Wörtern von Description 
for ( my $i=0; $i<=$count; $i++ ) {
	
	next if ( $ResultCountDesc >= $MaxCountClusterDesc );	#	 zähle nur die ersten X Ergebnisse als Cluster 
	next if ( $ResultHashRefUrl{$i} eq '' );				#	 überspringe leere elemente
	
	#	für alle einzelnen wörter aus dem array $i 
	for ( $m=0; $m<=$#{$CLUSTERDESC{$i}} ; $m++ ) {
		
		#	baue eine for schleife über alle $count einträge,
		#	diese scheife wird dann benutzt, um das element @{$CLUSTERDESC{$i}}[$m] mit @{$CLUSTERDESC{$j}}[0] bist @{$CLUSTERDESC{$j}}[$n] zu vergleichen
		for ($j=0; $j<=$count ; $j++ ) {

			next if ( $ResultCountDesc >= $MaxCountClusterDesc );
			next if ( $ResultHashRefUrl{$j} eq '' );	#	überspringe leere elemente
			next if ( $i == $j );						#	überspringe den vergleich des Arrays $i mit sich selbst

			#	vergleiche alle elemente von @{$CLUSTERDESC{$j}}[] mit @{$CLUSTERDESC{$i}}[$m]
			for ( $n=0; $n<=$#{$CLUSTERDESC{$j}} ; $n++ ) {
				
				next if ( $ResultCountDesc >= $MaxCountClusterDesc );
				$wordcount++;

				#	speed hacks - ignoriere alles was kürzer/gleich $IgnoreResultsShorterThan buchstaben ist
				next if ( length(@{$CLUSTERDESC{$i}}[$m]) <= $IgnoreResultsShorterThan );
				next if ( length(@{$CLUSTERDESC{$j}}[$n]) <= $IgnoreResultsShorterThan );
	
				my $StrOne	= @{$CLUSTERDESC{$i}}[$m] . " " . @{$CLUSTERDESC{$i}}[$m+1];
				my $StrTwo	= @{$CLUSTERDESC{$j}}[$n] . " " . @{$CLUSTERDESC{$j}}[$n+1];
				
				if ( lc($StrOne) eq lc($StrTwo) ) {
				
					$HashRefDoubleItems{$StrOne}++;

					if ( $HashRefDoubleItems{$StrOne} >= 2) {	#	ignoriere das vorkommen von doppelten clustern
					
					} else {
					
						# DEBU: print "Description: $StrOne sind gleich \n ";
												
						my $url		= \$ResultHashRefUrl{$i};
						my $title	= \$ResultHashRefTitle{$i};
						my $desc	= \$ResultHashRefDesc{$i};
						my $engine	= \$ResultHashRefEngine{$i};
						my $boost	= \$ResultHashRefBoost{$i};
						
						#print "$StrOne#\t#$url#\t#$title#\t#$desc#\#$engine#\t#$boost\n";
						push(@CLUSTERRESULTS, "$StrOne#\t#$url#\t#$title#\t#$desc#\#$engine#\t#$boost\n");

						#	entferne die cluster aus den ergebnislisten
						delete $ResultHashRefUrl{$i};
						delete $ResultHashRefTitle{$i};
						delete $ResultHashRefDesc{$i};
						delete $ResultHashRefEngine{$i};
						delete $ResultHashRefBoost{$i};

						$ResultCountDesc++;
					};

				};
			};
		};
	};
};


$HashRefDoubleItems = {};	#	lösche das hash mit den doppelten treffern

#	Vergleich von 2 Titelwörtern 
for ( my $i=0; $i<=$count; $i++ ) {
	
	next if ( $ResultCountTitle >= $MaxCountClusterTitle );		#	zähle nur die ersten 5 Ergebnisse als Cluster 
	next if ( $ResultHashRefUrl{$i} eq '' );					#	überspringe leere elemente
	
	#	für alle einzelnen wörter aus dem array $i 
	for ( my $m=0; $m<=$#{$CLUSTERTITLE{$i}} ; $m++ ) {
		
		#	baue eine for schleife über alle $count einträge,
		#	diese scheife wird dann benutzt, um das element @{$CLUSTERTITLE{$i}}[$m] mit @{$CLUSTERTITLE{$j}}[0] bist @{$CLUSTERTITLE{$j}}[$n] zu vergleichen
		for ( my $j=0; $j<=$count ; $j++ ) {

			next if ( $ResultCountTitle >= $MaxCountClusterTitle );
			next if ( $ResultHashRefUrl{$j} eq '' );
			next if ( $i == $j );

			#	vergleiche alle elemente von @{$CLUSTERTITLE{$j}}[] mit @{$CLUSTERTITLE{$i}}[$m]
			for ( my $n=0; $n<=$#{$CLUSTERTITLE{$j}} ; $n++ ) {
				
				next if ( $ResultCountTitle >= $MaxCountClusterTitle );
				$wordcount++;

				#	speed hacks - ignoriere alles was kürzer/gleich 4 buchstaben ist
				next if ( length(@{$CLUSTERTITLE{$i}}[$m]) <= $IgnoreResultsShorterThan );
				next if ( length(@{$CLUSTERTITLE{$j}}[$n]) <= $IgnoreResultsShorterThan );
	
				my $StrOne	= @{$CLUSTERTITLE{$i}}[$m] . " " . @{$CLUSTERTITLE{$i}}[$m+1];
				my $StrTwo	= @{$CLUSTERTITLE{$j}}[$n] . " " . @{$CLUSTERTITLE{$j}}[$n+1];
				#	my $pre		= "$i $m"; my $aft		= "$j $n";
	

				if ( lc($StrOne) eq lc($StrTwo) ) {
				
					$HashRefDoubleItems{$StrOne}++;

					if ( $HashRefDoubleItems{$StrOne} >= 2) {	# ignoriere das vorkommen von doppelten clustern
					
					} else {
					
						print "TITLE: $StrOne sind gleich \n ";
												
						my $url		= \$ResultHashRefUrl{$i};
						my $title	= \$ResultHashRefTitle{$i};
						my $desc	= \$ResultHashRefDesc{$i};
						my $engine	= \$ResultHashRefEngine{$i};
						my $boost	= \$ResultHashRefBoost{$i};
						
						push(@CLUSTERRESULTS, "$StrOne#\t#$url#\t#$title#\t#$desc#\#$engine#\t#$boost\n");
						$ResultCountTitle++;

						delete $ResultHashRefUrl{$i};
						delete $ResultHashRefTitle{$i};
						delete $ResultHashRefDesc{$i};
						delete $ResultHashRefEngine{$i};
						delete $ResultHashRefBoost{$i};

					};

				};
			};
		};
	};
};


my $s2 = Time::HiRes::time();
my $sec = $s2 - $s1;

print "vergleich von $wordcount wörtern dauerte $sec Sekunden\n";
print @NoClusterIDS;

###########
# GARBAGE #
###########

#} else {
#
###					$TempDoubleCount{$i}++;
#					
#					if ( $TempDoubleCount{$i} >= 2) {	#	ignoriere doppelte einträge
#					}else {
#						push(@NoClusterIDS, "$i\n");
#					};
#

# print @{$CLUSTERDESC{1}}[5]; # gebe aus der 1 description das 5 wort aus
# print $#{$CLUSTERDESC{$i}}; # hierdrin steht die anzahl der einträge für das array $i

# stringvergleich(vergleich von 2 zeichenketten), wobei vorher mittels lc() beiden zu vergleichende zeicheketten in kleinbuchstaben umgewandelt werden
				#if ( lc @{$CLUSTERDESC{$i}}[$m] eq lc @{$CLUSTERDESC{$j}}[$n] ) {
					# gleich sind Array $i und Array $i Wert $m und Array $j und Array $j Wert $n
				#	print "GLEICH: @{$CLUSTERDESC{$i}}[$m] und @{$CLUSTERDESC{$j}}[$n] \n";
				#	print "Zahlenkombination $i-$m und $j-$n\n";
				#};

# vergleiche das erste wort von description N mit dem ersten wort von Description N + 1
#for ($i=0; $i<=$count ; $i++) {
#	if ( lc @{$CLUSTERDESC{$i}}[1] eq lc @{$CLUSTERDESC{$i+1}}[1] ) {
#		print "@{$CLUSTERDESC{$i}}[1] und @{$CLUSTERDESC{$i+1}}[1] sind gleich \n";
#	};
#};

#if ( lc @{$CLUSTERDESC{$i}}[1] eq lc @{$CLUSTERDESC{$i+1}}[1] ) {
	#	print "@{$CLUSTERDESC{$i}}[1] und @{$CLUSTERDESC{$i+1}}[1] sind gleich \n";
	#};


#for ($i=0; $i<=$count ; $i++) {
#	for ( $j=0; $j<= $#{$CLUSTERDESC{$i}}; $j++ ){
#		#print @{$CLUSTERDESC{$i}}[$j] . " \n";
#		if ( @{$CLUSTERDESC{$i}}[$j] eq @{$CLUSTERDESC{$j}}[$j] ) {
#		#	print "@{$CLUSTERDESC{$i}}[$j] sind gleich @{$CLUSTERDESC{$j}}[$j]\n";
#		};
#		print "@{$CLUSTERDESC{$i}} sind gleich @{$CLUSTERDESC{$j}}\n";
#	};
#	exit;
#};

