<?php
	defined( "_VALID_PAGE_MONITOR" ) or die (_NODIRECTACCESS);
	
	class PreviewBrowser extends Module{
	
		/* Variables */
		var $arrayOfXMLFiles;
			// Array of XMLFiles along with their "folders".
		var $folderstack;
			// Folderstack.
		var $starterfolder;
			// Starting folder.
		var $parser;
			// XML parser to use.
		var $productListModule;
			// ProductListModule.
		var $params;
		var $onePageMargins;
			// Margins per page displayed ("top", "left", "bottom", "right");
		var $date;
			// Date of execution
	
		/* Constructor */
		function PreviewBrowser($p){
			if( !is_a($p, "ProductList") )
				die( _PRODUCTLISTMODULE_WRONGPARAM );
				
			// Super constructor
			parent::Module();
			
			// Init variables
			$moduleName = "PreviewBrowser 1.0";
			$this->folderstack = array();
			$this->productListModule = $p;
			$this->params = new Params;
			$this->onePageMargins = array( "top" => 20, "left" => 20, "bottom" => 20, "right" => 20 );
			$this->date = date($this->pm_config["date_format"]);
			
			// Set XML parser.
			if (!($this->parser = xml_parser_create()))
        die("Couldn't create parser.");
		}
		
		
		/* 
		 *	getFileListing()
		 *	Get a complete file listing for a folder pointed out by $pm_config["ftp_folder"].
		 *	This recursive function is entering each folder and searches for files that
		 *	match the .xml regex. Upon finding each file is added to a list along with its
		 *	path so the xml can be read and previews extracted.
		 *	Note: this method should not be used often. If the ftp folder contains
		 *	lots of files/folders this method is highly ineffective and time comsuming.
		 *	Please use getFileListingEx instead.
		*/
		public function getFileListing($starting_folder){
			unset( $this->arrayOfXMLFiles );
			$folder = $this->pm_config["ftp_folder"];
			$this->starterfolder = $folder . DIRECTORY_SEPARATOR . $starting_folder;
			$this->addToListAndTraverseFolderHierarchy($folder, true);
		}
		
		private function addToListAndTraverseFolderHierarchy($folder,$first){
			if( false == $first )
				array_push($this->folderstack, $folder);
				
			$relative_folder = $this->starterfolder . $this->fullpathfromstack();
			$page = NULL;

			if( $this->productListModule->getSelectedPage() != NULL && $this->productListModule->getSelectedPage() != $this->productListModule->getAllKey() ){
				$page = $this->productListModule->getSelectedPage();
			}

			if ($handle = opendir(/*$folder*/$relative_folder)){
					while (false !== ($file = readdir($handle))) {
						if( $file != "." && $file != ".." && $file != ".DS_Store" ){
							$isdir = is_dir($relative_folder . DIRECTORY_SEPARATOR . $file);
							
							if( true == $isdir ){
								$this->addToListAndTraverseFolderHierarchy($file, false);
							}else{
								if( ereg(".xml$", $file, $regs) ){
									// Add this XML filename to arrayOfXMLFiles, at key of page, and add to an array
									// existing at that key. This way we'll have an array of all the xml files for a
									// particualr page.
									if( !$page ){
										$path = $this->fullpathfromstack();
										if( ereg("/([0-9]+)+", $path, $regs1) ){
											$path = $regs1[1];
										}
										$this->arrayOfXMLFiles[$path][] = array("filename" => $file, "path" => $path );
									}else{
										$this->arrayOfXMLFiles[$page][] = array("filename" => $file, "path" => $this->fullpathfromstack() );
									}
								}
							}
					
						}
					}
				}else{
					echo "Could not open folder.";
				}
			if( false == $first )
				array_pop($this->folderstack);
		}
		
		private function fullpathfromstack(){
			$relative_folder = "";
			foreach( $this->folderstack as $value )
				$relative_folder = $relative_folder . DIRECTORY_SEPARATOR . $value;
			return $relative_folder;
		}
		
		private function parseAquiredXMLsAsListOfAllPages(){
			if( !$this->arrayOfXMLFiles )
				die (_NOPREVIEWSTOSHOW);

			$min_max_values = $this->getMinAndMaxValuesFromArrayOfXMLFiles($this->arrayOfXMLFiles);
			$min_xscale = $min_max_values['min_xscale'];
			$min_yscale = $min_max_values['min_yscale'];
			$max_xscale = $min_max_values['max_xscale'];
			$max_yscale = $min_max_values['max_yscale'];
			$min_set = false;
			$max_set = false;
			$img_min_size = $min_max_values["img_min_size"];
			$div_size["width"] = 2* $img_min_size["width"] + 2*10;
			$div_size["height"] = $img_min_size["height"] + 2*10;			
			
			$current_page = 0;
			$page_images_written = 0;
			
			$current_page = 1;
			$i = 0;
			
			// Przejdź po indeksach od 1 do nieskończoności.
			// Spróbuj pobrać element o indeksie z tabeli plików XML/stron. Jeżeli nie ma takiego,
			// należy uznać, że takiej strony nie ma.
			// Jeżeli istnieje, pobrany obiekt jest tablicą różnych wersji pliku w kolejności odrotnej.
			// Pod indeksem 0 jest array zawierająca informacje o najstarszym pliku, pod 1 jest array
			// o nowszej itd.
			$arrayOfXMLFiles_keys = array_keys($this->arrayOfXMLFiles);
			while( true ){
				$pageNumber = NULL;
				
				$should_add_dummy_page = false;
				$should_add_normal_page = false;
				
				$normal_page_newest_xml_file = NULL;
				$normal_page_newest_xml_path = NULL;
				$thumbnail_image = NULL;
				$max_image = NULL;
				$img_size = NULL;
				$thumbnail_image = NULL;
				$max_image = NULL;
				$filetime = NULL;
				$ready = NULL;
				
				if( $i < count($arrayOfXMLFiles_keys) ){
					$pageNumber= NULL;
					$found = false;
					foreach($arrayOfXMLFiles_keys as $kk){
						if( $kk == $current_page ){
							$pageNumber = $kk;
							break;
						}
					}
				 //$pageNumber = $arrayOfXMLFiles_keys[$i];
				 if( $pageNumber != $current_page ){
					 // Strona różni się od strony, ktorą mamy w liście stron/folderów.
					 // Wyświetlamy "pustą" stronę.
					 $should_add_dummy_page = true;
				 }else{
				 	// To jest normalna strona. Pobieramy informację o najnowszym pliku (ostatni plik xml
				 	// posortowany wg. alfabetu).
					$should_add_normal_page = true;
					$i++;
					
					foreach( array_reverse($this->arrayOfXMLFiles[$pageNumber]) as $xmlListingValue ){
						$normal_page_newest_xml_file = $xmlListingValue["filename"];
						$normal_page_newest_xml_path = $xmlListingValue["path"];
						$path = $this->starterfolder . DIRECTORY_SEPARATOR . $normal_page_newest_xml_path . DIRECTORY_SEPARATOR . $normal_page_newest_xml_file;
						$xmlFileAsString = file_get_contents($path);
				
						$xmlparser = new XMLParser($path);
						$img_info = $this->getPreviewThumnailAndImageDataFromXML($xmlparser, $min_max_values);
						$img_size = $img_info["img_size"];
						$thumbnail_image = $img_info["thumbnail_image"];
						$max_image = $img_info["max_image"];
						$ready = $img_info["ready"];
						break;
					}
				 }
				}else{
					break;
				}
				
				if( $should_add_dummy_page || $should_add_normal_page ){
					if( $current_page == 1 || $current_page % 2 == 0 ){
						$this->outDivForTwoPages($div_size["width"], $div_size["height"]);
					}					
					if( $current_page == 1 ){
						$this->outDivForOnePage($img_min_size["width"], $img_min_size["height"], $ready);
						$this->outDummyImage($img_min_size["width"], $img_min_size["height"], true);
						echo '</div>';
					}

					$this->outDivForOnePage($img_min_size["width"], $img_min_size["height"], $ready);
					$this->outOnePageHeader();
					echo $current_page . '</div>';

					if( $should_add_dummy_page ){
						$this->outDummyImage($img_min_size["width"], $img_min_size["height"]);
						echo '<br/><span class="nopage">' . date($this->pm_config["date_format"]) . '</span>';
					}else if( $should_add_normal_page ){
						$tmp_img_file = $this->pm_config["ftp_folder2http_folder"] . DIRECTORY_SEPARATOR . $this->productListModule->getPath() . DIRECTORY_SEPARATOR . $normal_page_newest_xml_path . DIRECTORY_SEPARATOR . $thumbnail_image;
						$tmp_full_img_file = $this->pm_config["ftp_folder"] . DIRECTORY_SEPARATOR . $this->productListModule->getPath() . DIRECTORY_SEPARATOR . $normal_page_newest_xml_path . DIRECTORY_SEPARATOR . $thumbnail_image;
						
						if( $max_image != NULL ){
							$get_copy = $_GET;
							unset($get_copy['page']);
							$get_copy['page'] = $normal_page_newest_xml_path;
							echo '<a href="?' . _PARAM_SHOWPAGEHISTORY . '=1' . $this->params->stringOfParametersFromGet($get_copy) . '">';
							if( $this->pm_config["show_tooltips_for_pages"] )
								//echo '<div>' . $this->additionalInfoOnPicture($tmp_full_img_file, $img_info) . '</div>';
								echo '<span>' . $this->additionalInfoOnPicture($tmp_full_img_file, $img_info) . '</span>';
						}
						
						if( !$ready && $this->params->onlyReadyPages )
							$this->outDummyImage($img_min_size["width"], $img_min_size["height"], false);
						else
							$this->outImage($tmp_img_file, $img_min_size["width"], $img_min_size["height"]);
							
						$filetime = filectime($tmp_full_img_file);
						
						if( $max_image != NULL ){
							echo "</a>" . chr(10);
						}
						
						echo '<br/>' . date($this->pm_config["date_format"], $filetime);
					}
					echo '</div>';
					
				} // should
					 
				if( $current_page % 2 != 0 ){
						 echo '</div>';
				}
				
				if( $current_page++ > 1000 )
					break;
			}
		}
		
		private function parseAquiredXMLsAsListOfPageHistory(){
			if( !$this->arrayOfXMLFiles )
				die ("Did not aquire list of previews.");

			$min_max_values = $this->getMinAndMaxValuesFromArrayOfXMLFiles($this->arrayOfXMLFiles);
			$min_xscale = $min_max_values['min_xscale'];
			$min_yscale = $min_max_values['min_yscale'];
			$max_xscale = $min_max_values['max_xscale'];
			$max_yscale = $min_max_values['max_yscale'];
			$img_min_size = $min_max_values["img_min_size"];
			$min_set = false;
			$max_set = false;
			
			
			foreach ($this->arrayOfXMLFiles as $key => $value){
				// Load contents of the xml file into a string.
				$chosenXMLFilename = NULL;
				$chosenXMLPath = NULL;
				
				// Odwracamy tablicę plików skjarzonych z daną stroną/folderem. W ten sposób nowsze pliki
				// (po nazwie) będziemy mieli na początku, czyli to, o co nam chodzi.
				$vv = array_reverse($value);
				foreach( $vv as $xmlListingValue ){
					$chosenXMLFilename = $xmlListingValue["filename"];
					$chosenXMLPath = $xmlListingValue["path"];
					
					$path = $this->starterfolder . DIRECTORY_SEPARATOR . $chosenXMLPath . DIRECTORY_SEPARATOR . $chosenXMLFilename;
					$xmlFileAsString = file_get_contents($path);
					
					$xmlparser = new XMLParser($path);
					$img_info = $this->getPreviewThumnailAndImageDataFromXML($xmlparser, $min_max_values);
					$img_size = $img_info["img_size"];
					$thumbnail_image = $img_info["thumbnail_image"];
					$max_image = $img_info["max_image"];
					$ready = NULL;
					$ready = $img_info["ready"];
					
					$this->outDivForOnePage($img_min_size["width"], $img_min_size["height"], $ready);
					echo '<div id="header">' . $this->params->selectedPage . '</div>';
					
					$thumb_image_filename = $this->pm_config["ftp_folder2http_folder"] . DIRECTORY_SEPARATOR . $this->productListModule->getPath() . DIRECTORY_SEPARATOR . $chosenXMLPath . DIRECTORY_SEPARATOR . $thumbnail_image;
					$tmp_full_img_file = $this->pm_config["ftp_folder"] . DIRECTORY_SEPARATOR . $this->productListModule->getPath() . DIRECTORY_SEPARATOR . $chosenXMLPath . DIRECTORY_SEPARATOR . $thumbnail_image;
					
					if( $max_image != NULL ){
						echo '<a href="' . $this->pm_config["ftp_folder2http_folder"] . DIRECTORY_SEPARATOR . $this->productListModule->getPath() . DIRECTORY_SEPARATOR . $chosenXMLPath . DIRECTORY_SEPARATOR . $max_image . '">';
						if( $this->pm_config["show_tooltips_for_pages"] )
							//echo '<div>' . $this->additionalInfoOnPicture($tmp_full_img_file, $img_info) . '</div>' . '';
							echo '<span>' . $this->additionalInfoOnPicture($tmp_full_img_file, $img_info) . '</span>' . '';							
					}
					
					
					if( !$ready && $this->params->onlyReadyPages )
							$this->outDummyImage($img_min_size["width"], $img_min_size["height"], false);
					else
							$this->outImage($thumb_image_filename, $img_size["width"], $img_size["height"]);
						
					if( $max_image != NULL )
						echo '</a>';
						
					echo '<br/>' . date($this->pm_config["date_format"], filectime($tmp_full_img_file)) . '</div>';
				}
			}
		}
		
		private function getMinAndMaxValuesFromArrayOfXMLFiles($array){
			// expects: array("filename" => $file, "path"/page => $this->fullpathfromstack() );
			$ret = array();
			
			$min_xscale = NULL;
			$min_yscale = NULL;
			$max_xscale = NULL;
			$max_yscale = NULL;
			$min_set = false;
			$max_set = false;
			$min_px_x_size = NULL;
			$min_px_y_size = NULL;
			$img_min_size = NULL;
			
			foreach ($array as $key => $value){
				foreach( $value as $xmlListingValue ){
					$chosenXMLFilename = $xmlListingValue["filename"];
					$chosenXMLPath = $xmlListingValue["path"];
					
					$path = $this->starterfolder . DIRECTORY_SEPARATOR . $chosenXMLPath . DIRECTORY_SEPARATOR . $chosenXMLFilename;
					$xmlFileAsString = file_get_contents($path);
					
					$xmlparser = new XMLParser($path);
					$root = $xmlparser->getRoot();
	
					if( !$min_xscale || !$min_yscale || !$max_yscale || !$max_xscale ){
						foreach( $root as $key => $v ){
							if( $v["name"] == "preview" ){
							 if( $min_xscale > $v["attributes"]["xscale"] )
								 $min_xscale = $v["attributes"]["xscale"];
							 if( $min_yscale > $v["attributes"]["yscale"] )
								 $min_yscale = $v["attributes"]["yscale"];				
						 
							 if( !$min_xscale )
								 $min_xscale = $v["attributes"]["xscale"];
							 if( !$min_yscale )
								 $min_yscale = $v["attributes"]["yscale"];
								 
							 if( $max_xscale < $v["attributes"]["xscale"] )
								 $max_xscale = $v["attributes"]["xscale"];
							 if( $max_yscale < $v["attributes"]["yscale"] )
								 $max_yscale = $v["attributes"]["yscale"];				
						 
							 if( !$max_xscale )
								 $max_xscale = $v["attributes"]["xscale"];
							 if( !$max_yscale )
								 $max_yscale = $v["attributes"]["yscale"];
								 
							 if( !$img_min_size["width"] )
								 $img_min_size["width"] = $v["attributes"]["width"];
							 if( !$img_min_size["height"] )
								 $img_min_size["height"] = $v["attributes"]["height"];
								 
							 if( $img_min_size["width"] > $v["attributes"]["width"] )
								 $img_min_size["width"] = $v["attributes"]["width"];	
							 if( $img_min_size["height"] > $v["attributes"]["height"] )
								 $img_min_size["height"] = $v["attributes"]["height"];
							}
						}
					}else{
						break;
					}
					
					$ret["min_xscale"] = $min_xscale;
					$ret["min_yscale"] = $min_yscale;
					$ret["max_xscale"] = $max_xscale;
					$ret["max_yscale"] = $max_xscale;
					$ret["img_min_size"] = $img_min_size;
				}
			}
			
			return $ret;
		}
		
		private function getPreviewThumnailAndImageDataFromXML($parser, $min_max_values){
			$min_xscale = $min_max_values['min_xscale'];
			$min_yscale = $min_max_values['min_yscale'];
			$max_xscale = $min_max_values['max_xscale'];
			$max_yscale = $min_max_values['max_yscale'];
			$thumbnail_image = NULL;
			$img_size["width"] = NULL;
			$img_size["height"] = NULL;
			$max_image = NULL;
			$username = NULL;
			$macaddress = NULL;
			$ready = false;
			
			$root = $parser->getRoot();
			foreach( $root as $key => $v ){
				if( strlen($v["data"]) < 3 )
					continue;
				if( $v["name"] == "preview" ){
					if( $v["attributes"]["xscale"] == $min_xscale || $v["attributes"]["yscale"] == $min_yscale ){
						$thumbnail_image = $v["data"];
						$img_size["width"] = $v["attributes"]["width"];
						$img_size["height"] = $v["attributes"]["height"];						
					}elseif( $v["attributes"]["xscale"] == $max_xscale || $v["attributes"]["yscale"] == $max_yscale )
						$max_image = $v["data"];
				}else if( $v["name"] == "macaddress" ){
					$macaddress = $v["data"];
				}else if( $v["name"] == "username" ){
					$username = $v["data"];				
				}else if( $v["name"] == "ready" ){
					$ready = $v["data"];
					if( $ready == 'false' )
						$ready = false;
				}
			}
			return array( "thumbnail_image" => $thumbnail_image, "img_size" => $img_size, "max_image" => $max_image,
				"username" => $username, "macaddress" => $macaddress, "min_xscale" => $min_xscale, "min_yscale" => $min_yscale,
				"ready" => $ready);
		}
		
		private function outDivForTwoPages($width, $height){
			$w = $width + 2*($this->onePageMargins["left"] + $this->onePageMargins["right"]);
			$h = $height + 2*($this->onePageMargins["top"] + $this->onePageMargins["bottom"]);
			
			$w *= $this->params->scale;
			$h *= $this->params->scale;			
			echo '<div class="twopages" style="' . 'width:'. $w .'px; height='. $h .'px;">' . chr(10);
		}
		
		private function outDivForOnePage($width, $height, $ready = false){
			$w = $width + 1*($this->onePageMargins["left"] + $this->onePageMargins["right"]);
			$h = $height + 1*($this->onePageMargins["top"] + $this->onePageMargins["bottom"]);
			
			$w *= $this->params->scale;
			$h *= $this->params->scale;
			
			$class = "onepage";
			if( $ready == "true" )
				$class = "onepage_ready";
			echo '<div class="' . $class .  '" style="' . 'width:'. $w .'px; height:'. $h .'px;">' . chr(10);
			echo '<div class="readystatus"><br/></div>' . chr(10);
		}
		
		private function outDummyImage($width, $height, $first = false){
			$src = $this->pm_config["http_location"] . DIRECTORY_SEPARATOR . "images/_blank.gif";
			$this->outImage($src, $width, $height, $first == false ? "dummy" : "dummy-first-page");
		}
		
		private function outOnePageHeader(){
			//echo '<div id="header" style="' . "font-size:" . $this->params->scale * 100 . "%;" . '">';
			echo '<div class="header">';
		}
		
		private function outImage($src, $width, $height, $class = NULL, $additionalStyle = NULL){
			$w = $width;
			$h = $height;
			$w *= $this->params->scale;
			$h *= $this->params->scale;	
			$c = '';
			if( $class )
				$c = ' class="' . $class . '" ';
				
			echo 	'<img src="' . $src . '" width="' . $w . '" height="' . $h . '"' . $c . ' alt="" style="' . '; ' . $additionalStyle . '"/>';
		}
		
		private function additionalInfoOnPicture($file_time, $page_info_from_xml){
			/* params */
			/*
				$file_time = ...
					$path = $this->starterfolder . DIRECTORY_SEPARATOR . $chosenXMLPath . DIRECTORY_SEPARATOR . $chosenXMLFilename;
					$xmlFileAsString = file_get_contents($path);
					
					$xmlparser = new XMLParser($path);
					$img_info = $this->getPreviewThumnailAndImageDataFromXML($xmlparser, $min_max_values);
			*/
			/*
				$page_info_from_xml = ...
			*/
			
			return '<b>' . _DATE . '</b> ' . date($this->pm_config["date_format"], filectime($file_time)) .
				'<br/><b>' . _FILENAME . '</b>: ' . $page_info_from_xml["thumbnail_image"] . 
				'<br/><b>' . _SCALEX . '</b>: ' . round($page_info_from_xml["min_xscale"]*100, 2) . '%'.
				'<br/><b>' . _SCALEY . '</b>: ' . round($page_info_from_xml["min_yscale"]*100, 2). '%' .
				'<br/><b>' . _MACADDRESS . '</b>: ' . $page_info_from_xml["macaddress"] .
				'<br/><b>' . _USERNAME. '</b>: ' . $page_info_from_xml["username"]
				;
		}
		
		/*
		 *	out()
		 *	Prints out module content.
		 */
		public function out(){
			$this->getFileListing($this->productListModule->getPath());
			if( !$this->params->showPageHistory ){
				$this->parseAquiredXMLsAsListOfAllPages();
				echo '</div>';
			}else
				$this->parseAquiredXMLsAsListOfPageHistory();
		}
	}

?>
