<?php
require_once 'model/map.php';
require_once 'model/access_point.php';
require_once 'model/location.php';
require_once 'model/rssi_record.php';


class Loc {
  public $_x;
  public $_y;
}
class HistogramFingerprint
{
  public $_location;
  public $_mesurement; //array of HistoValue
}

class Bean
{
  public $_value;
  public $_occurence;
}


class HistogramValue
{
  public $_macAddr;
  public $_value; //RSSIHistogram = vector<Bean>

  public function __construct($mac, $meas, $isMeas){
    if($isMeas) {
      $this->_macAddr=$mac;
      $map = $meas;
      ksort($map);
      foreach($map as $first=>$second)
      {
        $val = new Bean();
        $val->_value = $first;
        $val->_occurence = $second;
        $this->_value = $val;
      }
    }
    else{
      $this->_macAddr=$mac;
      $this->_value = $meas;
    }
  }

}


class structFunctions {

  public static function add_bean($histo,$b)
  {
    $i =0;
    foreach($histo as $histoBean)
    {
      if($histoBean->_value == $b->_value)
      {
        $histoBean->_occurence += $b->_occurence;
        return $histo;
      }
      $i++;
    }
    $histo[$i] = $b;
    return $histo;
  }

  public static function merge_histo($dest,$other)
  {
    foreach($b as $other)
    {
      add_bean($dest,$b);
    }
    return $dest;
  }

  public static function add_value($sample,$v)
  {
    $i =0;
    foreach($sample as $histoVal)
    {
      if($histoVal->_macAddr == $v->_macAddr)
      {
        merge_histo($histoVal->_value,$v->_value);
        return $sample;
      }
      $i++;
    }
    $sample[$i] = $v;
    return $sample;
  }

  public static function probability_histo($s1,$s2)
  {
    $sum_s1 = 0;
    $sum_s2 = 0;
    $p = 0;
    foreach($s1 as $bean){
      $sum_s1+=$bean->_occurence;
    }
    foreach ($s2 as $bean) {
      $sum_s2+=$bean->_occurence;
    }
    foreach($s1 as $bean){
      $v = $b->_value;
      $i=0;
      foreach($s2 as $b2)
      {
        if($b2->_value == $v)
        {
          break;
        }
        $i++;
      }
      if($i != count($s2)) {
        $p+=min($b->_occurence/$sum_s1,$s2[$i]/$sum_s2);
      }
    }
    return $p;
  }

  public static function probability($hf,$dev_measurement){
    $p = 1;
    foreach($hf as $v){
      $i=0;
      foreach($dev_measurement as $hv)
      {
        if($hv->_macAddr == $v->_macAddr)
        {
          break;
        }
        $i++;
      }
      if($i != count($dev_measurement)) {
        $p*=probability_histo($v->_value,$dev_measurement[$i]->_value);
      }
      else {
        $p=0;
      }
      if($p==0)
      {
        break;
      }
    }
    return $p;
  }

  public static function locate($current,$db){
    $p =0;
    $l;
    foreach($db as $f)
    {
      $tmpPos = probability($current,$f);
      if($p <$tmpPos)
      {
        $p=$tmpPos;
        $l = $f->_location;
      }

    }
    return $l;
  }

  public static function load_histogram_db()
  {

    // ----------------------------------------------------------------------------------------- //
    // ------------------------- Translation from DB to our Stuctures -------------------------- //
    // ----------------------------------------------------------------------------------------- //

    include 'bootstrap.php';


  $loc = $entityManager->getRepository('rssi_record')->createQueryBuilder('rs')->select('rs.location')->groupBy('rs.location')->getQuery()->getResult();

    foreach($loc as $l) {
      $ap = $entityManager->getRepository('rssi_record')->createQueryBuilder('rs')
        ->select('rs.access_point')
        ->groupBy('rs.location', 'rs.access_point')
        ->getQuery()
        ->getResult();
        $myHistoFinger = new HistogramFingerprint();
        foreach($ap as $a) {
          $myHistoVal = new HistogramValue();
          $beans = $entityManager->getRepository('rssi_record')->findBy(array('location' => $l.getId(), 'access_point' => $a.getId()));
          foreach($beans as $b) {
            $myBean = new Bean();
            $myBean->_value = $b.getValue();
            $myBean->_occurence = $b.getOccurences();
            array_push($myHistoVal->_value,$myBean);
          }
          $myHistoVal->_macAddr = $a.getMac_addr();
          array_push($myHistoFinger->_mesurement,$myHistoVal);
        }
        $tmpPos = $entityManager->getRepository('location')->findOneBy(array('id' => $l.getLocation()));
        $myLocation = new Location();
        $myLocation->_x=$tmpPos.getX();
        $myLocation->_y=$tmpPos.getY();
        $myHistoFinger->_location = $myLocation;
        array_push($db, $myHistoFinger);
      }
      return $loc;
  }


}
?>
