<?php
/**
 * @copyright (c) Kufer Software GmbH, Loisachstrasse 4, D-84453 Mühldorf
 */

class CompleteOrderByDefault
{
  private $dboperation;
  private $columnsInUse = array();
  private $defaultField;
  private $orderByAscArray;
  private $castToInt;
  private $prefix;
  private $lastOrderBy;
  private $orderbyattrs;

  public function __construct($dboperation, $pDefaultField, $pOrderByAsc, $pCastToInt, $pPraefix, $lastOrderBy, $orderbyattrs)
  {
    $this->defaultField = (array)$pDefaultField;
    $this->orderByAscArray = (array)$pOrderByAsc;
    $this->castToInt = (array)$pCastToInt;
    $prefixList = (array)$pPraefix;
    $this->prefix = array_map(function($prefix) {
      return (trim($prefix) != '') ? trim($prefix, '.') . '.' : '';
    }, $prefixList);
    $this->dboperation = $dboperation;
    $this->lastOrderBy = $lastOrderBy;
    $this->orderbyattrs = $orderbyattrs;
  }

  public function getCompleteOrderByDefault()
  {
    return ' ORDER BY ' . implode(', ', $this->getOrderByAry());
  }

  private function getOrderByAry()
  {
    $orderByAry = array_map(array($this, 'getOrderByEntry'), $this->getOrderByObjectsArray());
    $orderByAry[] = $this->getLastOrderBy($this->lastOrderBy);

    return array_diff($orderByAry, array(null));
  }

  
  private function getOrderByEntry($orderByObj)
  {
    $name = $orderByObj->getNameMitPrefix();
    if (!in_array($name, $this->columnsInUse)) {
      $this->columnsInUse[] = $name;

      $name = $orderByObj->castToType($name, $this->dboperation->dbparser);

      return ltrim($this->dboperation->dbparser->orderby($name, $orderByObj->getOrderAsString()));
    }

    return null;
  }

  private function getLastOrderBy($lastOrderBy)
  {
    $lastOrderByAlreadySet = $this->checkIfLastOrderByIsAlreadySet($lastOrderBy);

    if (!$lastOrderByAlreadySet && $lastOrderBy != '') {
      return $lastOrderBy;
    }

    return null;
  }

  private function checkIfLastOrderByIsAlreadySet($lastOrderBy)
  {
    $func = function($lastOrderBy, $orderByObj) {
      return $orderByObj->getNameOhnePrefix() == $lastOrderBy || $orderByObj->getNameOhnePrefix() == preg_replace('/.*\\./', '', $lastOrderBy);
    };

    return ArrayOperations::in_array_u($lastOrderBy, $this->getOrderByObjectsArray(), $func);
  }

  private function getOrderByObjectsArray()
  {
    $orderByObjects = array();
    for ($i = 0; $i < 10; $i++) {
      $orderBy = null;
      if (isset($this->orderbyattrs[$i])) {
        $orderBy = $this->orderbyattrs[$i];
      } elseif (isset($this->defaultField[$i])) {
        $asc = isset($this->orderByAscArray[$i]) ? $this->orderByAscArray[$i] : true;
        $orderBy = new OrderBy($this->defaultField[$i], $asc);
      }

      if (!is_null($orderBy)) {
        $orderBy->setCastToInt(isset($this->castToInt[$i]) ? $this->castToInt[$i] : false);
        $orderBy->setPrefix(isset($this->prefix[$i]) ? $this->prefix[$i] : $this->prefix[0]);
        $orderByObjects[] = $orderBy;
      }
    }

    return $orderByObjects;
  }
}