<?php
/*=======================================================================
 *
 * grid.inc.php
 *
 * Autor: Marc Vollmann
 *  
 =======================================================================*/   


// include_once ("../include/xxxx.inc.php");

// global $db, $PHP_SELF, $hq_id, $emp_id, $usr_id;


// CLASS for generating grid with content

class Grid {

  // ATTRIBUTES

  // Associative array for global grid parameters
  // Examples:
  // Define abbreviations for names or part of names for tags (class names, ID tags, tag names, etc.)
  // gridParameters["ct_tag_prefix"]    = "grid";  // base prefix of all container tags
  // gridParameters["ct_tag_headline"]  = "hl";    // headline : hl
  // gridParameters["ct_tag_body"]      = "bd";    // body : bd
  // gridParameters["ct_col_width"]     = "700px"; // Width of the container
  // Output following "gridParameters["css_output"]" to define the entire CSS block (<tyle>....</style>) for the HTML page
  // gridParameters["css_output"] = "
  //   ." . gridParameters["ct_tag_prefix"] . " {padding:5px; margin:5px;}; 
  //   ." . gridParameters["ct_tag_prefix"] . "_" . $gridParameters["ct_tag_headline"] . " {padding:5px; background-color:#1b12b9; color:white;};
  //   ." . gridParameters["ct_tag_prefix"] . "_" . gridParameters["ct_tag_body"] . " {min-height:150px; padding:5px; background-color:#1b12b9; color:white;};
  // ";
  // ....
  private $gridParameters = array();


  // Array with rows as first component and columns as second (2D array with 2D sub arrays and so on)
  // If "is_array($gridStruct[x][y]) == true" then this item has a sub-grid
  // The itemID is the element ID of the container item (e.g. <div id="itemID">)
  // Each headline and corresponding body ID of a container can be derived from the container ID "itemID"
  // -----------------------------
  // Example 01: 5 rows and 1 col, 3rd row is an array
  //   $gridStruct[0][0] = itemID
  //   ....
  //   $gridStruct[2][0] = array(1,2)
  //      => container $gridStruct[2][0] has 1 row and 2 cols
  //      $gridStruct[2][0][0][0] = itemID
  //      $gridStruct[2][0][0][1] = itemID
  //      => One if that sub-)items can be an array again
  //   ....
  //   $gridStruct[4][0] = itemID
  // -----------------------------
  // Example 02: 3 rows and 2 cols
  //   $gridStruct[0][0] = itemID
  //   $gridStruct[0][1] = itemID
  //   $gridStruct[1][0] = itemID
  //   $gridStruct[1][1] = itemID
  //   $gridStruct[2][0] = itemID
  //   $gridStruct[2][1] = itemID
  //   ....
  public $gridStruct = array();


  // Associative array with all items of the grid as a list (independent from the grid structure).
  // The item ID is the key of the array. The second component is the (CSS-)type
  // Example 01: Item with ID "grid_ct_00_01"
  //   $gridItemList["grid_ct_00_01"]["class"] = array  : class names associated to this container ....)
  //   $gridItemList["grid_ct_00_01"]["style"] = array  : styles associated to this container ....)
  //   $gridItemList["grid_ct_00_01"]["html"] =  string : combined output (e.g. "<div>") with all tags "class", "id", "name", etc. ....)
  //   $gridItemList["grid_ct_00_01"]["...."]  = ....
  public $gridItemList = array();    


  // METHODS

  // Constructor
  function __construct($initialColWidth = "", $gridMatrix = array(), $gridParameters = array(), $gridStruct = array()) {
  	// Add or modify grid parameters
  	if (!is_array($gridParameters)) : $gridParameters = array(); endif;
    $this->setDefaultGridParameters($initialColWidth, $gridParameters);
  	// Define new structure or add sub-structure items
  	if (!is_array($gridStruct)) : $gridStruct = array(); endif;
    $gridStruct = $this->setDefaultGridStructure($gridMatrix);  // Also inserts items to class attribute "$gridItemList"
  	$this->gridParameters["grid_matrix"] = $gridMatrix;   // Remember the dimensions of the container array, e.g. regarding the container page counter
  	$this->gridParameters["container_page_counter"] = 1;  // Inits the counter for a page to use the NEXT container
  }

  // Set global parameters (like tag names, class valuess, etc.)
  private function setDefaultGridParameters($initialColWidth, $gridParameters) {
  	$this->gridParameters["ct_tag_prefix"]    = "grid_ct";  // base prefix of all container tags 	
  	$this->gridParameters["ct_tag_headline"]  = "hl";       // headline : hl
  	$this->gridParameters["ct_tag_body"]      = "bd";       // body : bd
  	if ($initialColWidth == "") : $initialColWidth = "700px"; endif;
    $this->gridParameters["ct_col_width"] = $initialColWidth;    // Init width of the container
  	// CSS output for HTML
  	// Examples
  	// .grid_ct {padding:5px; margin:5px;}
  	// .grid_ct_ht {padding:5px; background-color:#1b12b9; color:white;}
  	// .grid_ct_bd {min-height:150px; padding:5px; background-color:#1b12b9; color:white; }
  	// ....
  	$this->gridParameters["output_css"] = " 
      ." . $this->gridParameters["ct_tag_prefix"] . " {float:left; padding:5px; margin:5px; width:" . $this->gridParameters["ct_col_width"] . "; font-size:10pt; font-family:Helvetica,Arial; font-style:normal; font-weight:normal;}
      ." . $this->gridParameters["ct_tag_prefix"] . "_" . $this->gridParameters["ct_tag_headline"] . " {min-height:22px; padding:5px; background-color:#1b12b9; color:white;}
      ." . $this->gridParameters["ct_tag_prefix"] . "_" . $this->gridParameters["ct_tag_body"] . " {min-height:150px; padding:5px; background-color:#97bcFF; color:white;}
    ";
    // Overwrite default values with new values of the same keys and add new values
    $this->gridParameters = array_merge($this->gridParameters, $gridParameters);
  }

  // Generates the DEFAULT grid structure
  private function createGridContainer($row, $col) {
  	$prefix     = $this->gridParameters["ct_tag_prefix"];
    $hl         = $this->gridParameters["ct_tag_headline"];
    $bd         = $this->gridParameters["ct_tag_body"];
    $pair = pad($row, 2, "0") . "_" . pad($col, 2, "0");
    $itemID = $prefix . "_" . $pair;                  // item ID of the container: gridStruct[1][2] = "grid_ct_02_01"
    $this->gridStruct[$row][$col] = $itemID;
    $this->gridItemList[$itemID]["class"] = $prefix;  // class(es) of the container gridItemList["grid_ct_02_01"] = "grid_ct";
    // HTML output of the container containing headline an body with derived IDs and class(es)
    $debugArrOut = "";
    // $debugArrOut = array("HEADLINE " . $pair, "BODY " . $pair);
    $htmlCt = "<div class=\"" . $prefix . "\" id=\"" . $itemID . "\">\n"
            . "  <div class=\"" . $prefix . "_" . $hl . "\" id=\"" . $itemID . "_" . $hl . "\">&nbsp;" . $debugArrOut . "</div>\n"
            . "  <div class=\"" . $prefix . "_" . $bd . "\" id=\"" . $itemID . "_" . $bd . "\">&nbsp;" . $debugArrOut . "</div>\n"
            . "</div>\n";
    $this->gridItemList[$itemID]["html"] = $htmlCt;
    return $htmlCt;
  }

  // Generates the DEFAULT grid structure
  private function setDefaultGridStructure($gridMatrix = array(3,2)) {
  	$rows = $gridMatrix[0];
  	$cols = $gridMatrix[1];
    $this->gridParameters["output_html"] = "";  // Init
  	for ($r = 0; $r < $rows; $r++) :
  	    $this->gridParameters["output_html"] .= "<div style=\"clear:left; height:0px;\"></div>";
  	    for ($c = 0; $c < $cols; $c++) :
  	        $this->gridParameters["output_html"] .= $this->createGridContainer($r, $c);
  	    endfor;
    endfor;
  }

  // Adds a container to the end of the base structure
  // TO BE DONE
  private function addGridContainer($row, $col) {
  	// ....
    $this->createGridContainer($row, $col);
    // ....
  }

  // Inits the counter for a page to use the NEXT container
  public function resetContainerPageCounter () {
  	$this->gridParameters["container_page_counter"] = 1;
  }

  // Gets the value of the current page counter
  public function getContainerPageCounter () {
  	return $this->gridParameters["container_page_counter"];
  }

  // Increments the current counter of a page to use the NEXT container
  // Returns container page counter values
  // $retMode: "0" or empty <=> returns the array(row, col) regarding current container ID
  //           "1" returns the current page counter by itself and increments it for the next call
  //           "2" returns the ID of the container
  public function getNextContainerPageCounter ($retMode = "0", $noIncrement = "") {
  	$ctPageCounter = $this->gridParameters["container_page_counter"];
  	if ($noIncrement == "") :
  	   $this->gridParameters["container_page_counter"]++;
  	endif;
  	if ($retMode == "1") :
  	   return $ctPageCounter;
  	else :
  	  $gridMatrix = $this->gridParameters["grid_matrix"];
    	$row = floor($ctPageCounter / $gridMatrix[1]);
  	  $col = ($ctPageCounter % $gridMatrix[1]) - 1;
  	  if ($col < 0) :
  	     $row--;
  	     $col = $gridMatrix[1] - 1;
  	  endif;
    	if ($retMode == "2") :
  	     return $this->gridStruct[$row][$col];  // Return item ID
  	  else :
  	     return array($row, $col);
  	  endif;  	   
  	endif;
  }

  // Returns the current counter of a page (without automatic increment)
  // $retMode: desciption look for "getNextContainerPageCounter()"
  // $mode: 
  public function getCurrentContainerPageCounter ($retMode = "0") {
  	return $this->getNextContainerPageCounter($retMode, "1");
  }

  // Gets single item parameter by key
  public function getGridItemParameter ($key) {
  	return $this->gridParameters[$key];
  }

  // Sets single item parameter by key and value
  public function setGridItemParameter ($key, $val) {
  	$this->gridParameters[$key] = $val;
  }

  // Returns a JS code line
  // Examples:
  // Add a "class" to an item         => setContainerProperty("itemID", "addClass", $cssClassName, "");
  // Remove a "class" to an item      => setContainerProperty("itemID", "removeClass", $cssClassName, "");
  // Set html content to an item      => setContainerProperty("itemID", "html", $htmlContent, "");
  // Set style for an item            => setContainerProperty("itemID", "css", "background-color", $bgColor);
  // ....
  public function jsContainerProperty ($itemID, $propertyType, $propertyName = "", $propertyVal = "", $propertyQuote = "'") {
  	return "$('#" . $itemID . "')." . $propertyType . "(" . ($propertyName != "" ? $propertyQuote . $propertyName . $propertyQuote : "") . ($propertyVal != "" ? ($propertyName != "" ? ", " : "") . $propertyQuote . $propertyVal . $propertyQuote : "") . ");\n";
  }

  // Short call for setting CSS attributes to an item [Calls function jsContainerProperty]
  public function gridSetCss ($row, $col, $attributeArr = array(), $childSuffix = "") {
  	$retStr = "";
  	$itemID = $this->gridStruct[$row][$col] . ($childSuffix != "" ? "_" . $childSuffix : "");
  	$attributeArrLen = count($attributeArr);
    for ($i = 0; $i < $attributeArrLen; $i += 2) :
       // $fs .= $attributeArr[$i] . "='" . $attributeArr[$i + 1] . "'";       
       $retStr .= $this->jsContainerProperty($itemID, "css", $attributeArr[$i], $attributeArr[$i + 1]);
    endfor;
    return $retStr;
  }

  // Short call for setting HTML content to an item [Calls function jsContainerProperty]
  public function gridSetContent ($row, $col, $content = "", $childSuffix = "", $propertyType = "html", $propertyQuote = "'") {
  	$retStr = "";
  	$itemID = $this->gridStruct[$row][$col] . ($childSuffix != "" ? "_" . $childSuffix : "");
  	$retStr .= $this->jsContainerProperty($itemID, $propertyType, "", $content, $propertyQuote);
    return $retStr;
  }

  // Sets HTML content to an item as short call for function "gridSetContent()"
  public function gridSetHtml ($row, $col, $content = "", $childSuffix = "", $propertyQuote = "'") {
    return $this->gridSetContent($row, $col, $content, $childSuffix, "html", $propertyQuote);
  }

  // Sets TEXT content to an item as short call for function "gridSetContent()"
  public function gridSetText ($row, $col, $content = "", $childSuffix = "", $propertyQuote = "'") {
    return $this->gridSetContent($row, $col, $content, $childSuffix, "text", $propertyQuote);
  }

  // Short call for hiding/showing an item [Calls function jsContainerProperty]
  public function gridHideShow ($row, $col, $hideShow = "hide") {
  	$itemID = $this->gridStruct[$row][$col];
  	return $this->jsContainerProperty($itemID, $hideShow);
  }

  // Short call for hiding remaining containers without content
  public function gridHideRemaining () {
  	$gridJsOut = "";
  	// Get number of containers of the page object
  	$gridMatrix = $this->gridParameters["grid_matrix"];
  	$numOfPageContainers = $gridMatrix[0] * $gridMatrix[1];
    $gridPageCounter = $this->getContainerPageCounter();
    for ($c = $gridPageCounter; $c <= $numOfPageContainers; $c++) :
        $gridMatrix = $this->getNextContainerPageCounter();
        $gridJsOut .= $this->gridHideShow($gridMatrix[0], $gridMatrix[1]);
    endfor;
    return $gridJsOut;
  }
}
?>
