<?php
/**
 * Part of southprojects Grid data on demand example.
 *
 * Copyright (c) 2006 by SouthProjects
 * http://www.southprojects.com
 * Santiago, Chile,
 * Version 1.2 Dec 2006.
 * All rights reserved.
 */

// phone_ondemand.php?args={"currentPage":0,"sortColumn":null,"sortDesc":null,"filters":[]}
 
 
/* $Id: phone_ondemand.php 4960 2006-10-30 19:22:36Z alex $ */

require_once 'JSON.php';
$objJsonConverter = new Services_JSON();

// Get arguments in JSON format
$objArgs = array();
if (!empty($_GET['args'])) {
  $objArgs = $objJsonConverter->decode(stripslashes($_GET['args']));
}


// Get data in JSON format from file
$objData = $objJsonConverter->decode(file_get_contents('phone_ondemand.txt'));

// Returns cell value to display
function getCellValueString($objCell) {
  $strValue = '';
  if (isset($objCell->{'v'})) {
    $strValue = $objCell->{'v'};
  }
  return $strValue;
}

// Returns cell value to compare
function getCellValueCompare($objCell) {
  if (isset($objCell->{'c'})) {
    return $objCell->{'c'};
  }
  return getCellValueString($objCell);
}

// Comparison function
function cmpKeys($left, $right) {
  if ($left{'c'} == $right{'c'}) {
    return 0;
  }
  return ($left{'c'} < $right{'c'}) ? -1 : 1;
}

// Returns range of values of the specified column
function getColumnRange($objData, $iCol) {
  // Get array of keys
  $arrKeys = array();
  // Auxiliary associative array
  $objKeys = array();
  // Iterate over rows
  if (empty($objData) || empty($objData->{'rows'})) {
    return null;
  }
  $arrRows = $objData->{'rows'};
  $iRows = count($arrRows);
  for ($iRow = 0; $iRow < $iRows; $iRow++) {
    // Get row
    if (empty($arrRows[$iRow]) || empty($arrRows[$iRow]->{'cells'})) {
      continue;
    }
    $objRow = $arrRows[$iRow];
    // Get cell
    if (empty($arrRows[$iRow]->{'cells'}[$iCol])) {
      continue;
    }
    $objCell = $arrRows[$iRow]->{'cells'}[$iCol];
    // Get cell value
    $strKey = getCellValueString($objCell);
    if (!isset($objKeys[$strKey])) {
      array_push($arrKeys, array(
        'v' => $strKey,
        'c' => getCellValueCompare($objCell)
      ));
      $objKeys[$strKey] = true;
    }
  }
  $iKeys = count($arrKeys);
  if (!$iKeys) {
    // Empty array
    return null;
  }
  // Sort array of keys
  usort($arrKeys, "cmpKeys");
  // Return range of column values
  return array(
    'min' => $arrKeys[0]{'c'},
    'minValue' => $arrKeys[0]{'v'},
    'max' => $arrKeys[$iKeys - 1]{'c'},
    'maxValue' => $arrKeys[$iKeys - 1]{'v'},
    'values' => $arrKeys
  );
}

if (!empty($objData) && !empty($objData->{'fields'}) &&
 !empty($objData->{'rows'})) {
  $arrFields = $objData->{'fields'};
  $iCols = count($arrFields);
  $arrRows = $objData->{'rows'};

  // Set totalRows
  $objData->{'totalRows'} = count($arrRows);

  // Set columnRange for the 1-st column
  if (!empty($arrFields[0])) {
    $objData->{'fields'}[0]->{'columnRange'} = getColumnRange($objData, 0);
  }
  // Set columnRange for the 4-th column
  if (!empty($arrFields[3])) {
    $objData->{'fields'}[3]->{'columnRange'} = getColumnRange($objData, 3);
  }
  // Set columnRange for the 6-th column
  if (!empty($arrFields[5])) {
    $objData->{'fields'}[5]->{'columnRange'} = getColumnRange($objData, 5);
  }

  // Apply filters
  if (!empty($objArgs) && !empty($objArgs->{'filters'})) {
    $arrFilters = $objArgs->{'filters'};
    // Columns having text filter
    $arrTextFilters = array();
    // Iterate over columns
    for ($iCol = 0; $iCol < $iCols; $iCol++) {
      if (empty($arrFilters[$iCol])) {
        continue;
      }
      $objFilter = $arrFilters[$iCol];
      // Set filters
      if (!empty($objFilter->{'hiddenValues'})) {
        $objData->{'fields'}[$iCol]->{'hiddenValues'} =
         $objFilter->{'hiddenValues'};
      }
      if (isset($objFilter->{'minValue'})) {
        $objData->{'fields'}[$iCol]->{'minValue'} = $objFilter->{'minValue'};
      }
      if (isset($objFilter->{'maxValue'})) {
        $objData->{'fields'}[$iCol]->{'maxValue'} = $objFilter->{'maxValue'};
      }
      if (isset($objFilter->{'textFilter'})) {
        $objData->{'fields'}[$iCol]->{'textFilter'} =
         $objFilter->{'textFilter'};
      }
      // Apply filters
      if (!empty($objFilter->{'hiddenValues'}) ||
       isset($objFilter->{'minValue'}) || isset($objFilter->{'maxValue'})) {
        // Iterate over rows
        for ($iRow = count($arrRows) - 1; $iRow >= 0; $iRow--) {
          $objRow = $arrRows[$iRow];
          if (empty($objRow) || empty($objRow->{'cells'}) ||
           empty($objRow->{'cells'}[$iCol])) {
            // Remove row
            array_splice($arrRows, $iRow, 1);
            continue;
          }
          // Get cell
          $objCell = $objRow->{'cells'}[$iCol];
          // Remove row if value of the cell is hidden
          if (!empty($objFilter->{'hiddenValues'}) &&
           array_search(getCellValueString($objCell),
            $objFilter->{'hiddenValues'}) !== false) {
            // Remove row
            array_splice($arrRows, $iRow, 1);
            continue;
          }
          // Remove row if value of the cell is lesser then min value
          if (isset($objFilter->{'minValue'}) &&
           $objFilter->{'minValue'} > getCellValueCompare($objCell)) {
            // Remove row
            array_splice($arrRows, $iRow, 1);
            continue;
          }
          // Remove row if value of the cell is greater then max value
          if (isset($objFilter->{'maxValue'}) &&
           $objFilter->{'maxValue'} < getCellValueCompare($objCell)) {
            // Remove row
            array_splice($arrRows, $iRow, 1);
            continue;
          }
        }
      }
      // Check text filter
      if (isset($objFilter->{'textFilter'})) {
        array_push($arrTextFilters, $iCol);
      }
    }
    // Apply text filters
    $iTextFilters = count($arrTextFilters);
    if ($iTextFilters) {
      // Iterate over rows
      for ($iRow = count($arrRows) - 1; $iRow >= 0; $iRow--) {
        $objRow = $arrRows[$iRow];
        // Indicates that row should be removed
        $boolRemove = true;
        // Iterate over filters
        for ($iFilter = 0; $iFilter < $iTextFilters; $iFilter++) {
          // Column number
          $iCol = $arrTextFilters[$iFilter];
          // Get cell
          $objCell = $objRow->{'cells'}[$iCol];
          // Get value
          $strValue = getCellValueString($objCell);
          // Get filter
          $strFilter = $arrFilters[$iCol]->{'textFilter'};
          // Search text fragment
          if (strpos($strValue, $strFilter) !== false) {
            $boolRemove = false;
            break;
          }
        }
        // Remove row if text fragment not found
        if ($boolRemove) {
          // Remove row
          array_splice($arrRows, $iRow, 1);
        }
      }
    }
  }

  // Sort
  if (!empty($objArgs) && isset($objArgs->{'sortColumn'})) {
    $iSortColumn = $objArgs->{'sortColumn'};
    $lt = -1;
    $gt = 1;
    if (isset($objArgs->{'sortDesc'}) && $objArgs->{'sortDesc'}) {
      $lt = 1;
      $gt = -1;
    }
    // Comparison function
    function cmpRows($left, $right) {
      global $iSortColumn, $lt, $gt;
      // Get values to compare
      if (empty($left) || empty($right) || empty($left->{'cells'}) ||
       empty($right->{'cells'}) || empty($left->{'cells'}[$iSortColumn]) ||
       empty($right->{'cells'}[$iSortColumn])) {
        return 0;
      }
      $leftVal = getCellValueCompare($left->{'cells'}[$iSortColumn]);
      $rightVal = getCellValueCompare($right->{'cells'}[$iSortColumn]);
      if ($leftVal == $rightVal) {
        // Compare other columns (always in ascending order)
        $iCols = count($left->{'cells'});
        for ($iCol = 0; $iCol < $iCols; $iCol++) {
          if ($iCol == $iSortColumn) {
            continue;
          }
          if (empty($left->{'cells'}[$iCol]) ||
           empty($right->{'cells'}[$iCol])) {
            continue;
          }
          $lVal = getCellValueCompare($left->{'cells'}[$iCol]);
          $rVal = getCellValueCompare($right->{'cells'}[$iCol]);
          if ($lVal == $rVal) {
            continue;
          }
          return ($lVal < $rVal) ? -1 : 1;
        }
        return 0;
      }
      return ($leftVal < $rightVal) ? $lt : $gt;
    }
    // Sort data
    usort($arrRows, "cmpRows");
  }

  // Set displayedRows
  $objData->{'displayedRows'} = count($arrRows);

  // Apply paging (10 rows per page)
  $iRowsPerPage = 10;
  $iCurrentPage = 0;
  if (!empty($objArgs) && isset($objArgs->{'currentPage'})) {
    $iCurrentPage = $objArgs->{'currentPage'};
    if ($iCurrentPage < 0) {
      $iCurrentPage = 0;
    }
  }
  $iFirst = $iCurrentPage * $iRowsPerPage;
  if ($iFirst && $iFirst >= count($arrRows)) {
    $iCurrentPage--;
    $iFirst = $iCurrentPage * $iRowsPerPage;
  }
  $arrRows = array_slice($arrRows, $iFirst, $iRowsPerPage);

  // Set currentPage
  $objData->{'currentPage'} = $iCurrentPage;

  $objData->{'rows'} = $arrRows;
}

// Output result in JSON format
echo $objJsonConverter->encode($objData);

?>
