<?php

// include BaseModel if available
include_once(realpath(dirname(__FILE__))."/mfBaseModel.php");

class mfBaseController {
	protected $log;
  protected $needlogin = false;
  protected $request;
	private $mfAction;
	private $mfDBI;
	private $mfLayout;
	private $mfMenu;
	private $mfUser;
  private $mod;
  private $action;
	
	public function __construct($params = NULL) {
		// load logging facility
		$this->log = mfLoghandler::singleton();
		
    $this->mod = $params['mod'];
    $this->action = $params['action'];
    
		// run custom constructor init()
		if(method_exists($this,"init")) {
			$this->init($params);
		}
    
		if(!defined('MFUSELOGIN')) define('MFUSELOGIN',false);
		if(!defined('MFUSEMENU')) define('MFUSEMENU',false);
		
		if(MFUSELOGIN) {
			// if protected area and not logged in, redirect to mfLogin
			if($this->needlogin==true) {
				if(!mfLoginController::isLoggedIn()) {
					// Save original request
					//$params['mfLoginGet']=$_GET; // TODO: some better way to preserve request while logging in
          $params["mfLoginUrl"]=$_SERVER['REQUEST_URI'];
					if($params['action']) {
            unset($params['action']);
					}
          
          if($this->loginTemplate) {
            $params['mfLoginTemplate']=$this->loginTemplate;
          }
					// Redirect to Loginform
					$temp=new mfLoginController($params);
          return 0;
				} else {
					$this->mfUser=mfUser::singleton();
				}
			}
		}

		if(MFUSEMENU) {
			// Load mfMenu for menu display
			$this->mfMenu=new mfMenuController();
			if($this->mfMenu) {
				$this->layout()->set("MenuItems",$this->mfMenu);
			}
		}
		
    // set default template variables
    $this->layout()->set('mod',$this->mod);
    $this->layout()->set('action',$this->action);
    
    // include and run global init file
    if(defined("MFBASECONTROLLER_INIT_INCLUDE_FILE")) {
      include MFBASECONTROLLER_INIT_INCLUDE_FILE;
    }
    
    $this->request = new mfRequest($params);
    
		// now run action
		if($params['action']) {
			$this->__call($params['action'],$params);
		} else {
			if(method_exists($this,"index")) {
				$this->__call("index",$params);
			}
		}
	}
	
	protected function user() {
		if(!MFUSELOGIN) {
			trigger_error("mvcfronk: Tried to access mfBaseController::user(), though MFUSELOGIN is set to false.", E_USER_WARNING);
			return false;
		}
		if(!$this->mfUser) {
			$this->mfUser=mfUser::singleton();
		}
		return $this->mfUser;
	}
	
	protected function layout() {
		if(!is_object($this->mfLayout)) {
			$this->mfLayout = Layout::singleton();
		}
		return $this->mfLayout;
	}
	
	
	protected function db() {
		$args=func_get_args();
		
		// if no arguments, just return a DB instance
		if(!$args) {
      // don't allow managed FronkDB instance, but new custom instance is allowed
      if(!FRONKDB) {
        return false;
      }
			if(!is_object($this->mfDBI)) {
				$this->mfDBI=FronkDB::singleton();
				
			}
			return $this->mfDBI;
		} else {
			// else return a new instance
			var_dump($args);
			$dbhost=$args[0];
			$dbuser=$args[1];
			$dbpass=$args[2];
			$dbname=$args[3];
			return $this->getNewDBInstance($dbhost,$dbuser,$dbpass,$dbname);
		}
		
	}

	public function __call($name,$params) {
		if(method_exists($this,$name)) {
      return call_user_func(array($this, $name), $params);
		} else { // if function doesn't exist, maybe it's an Action
			$funcname=lcfirst($name);
			if(!preg_match('/Action$/',$name)) {
				$funcname.="Action";
			}
			
			if(method_exists($this,$funcname)) {
        return call_user_func(array($this, $funcname), $params);
			} else {
				throw new Exception(get_class($this).": $name not found",404);
			}
		}
	}
  
  public function __get($name) {
    if($name == "db") {
      return $this->db();
    }
    if($name == "layout") {
      return $this->layout();
    }
    
    return null;
  }

  
  protected function logout() {
		mfLoginController::logout();
		$this->redirect(DEFAULT_ROUTE);
	}

  /*
	 *  private internal functions
	 */	
	
	private function getNewDBInstance($dbhost=false,$dbuser=false,$dbpass=false,$dbname=false) {
		if(!$dbhost) $dbhost=FRONKDB_DBHOST;
		if(!$dbuser) $dbhost=FRONKDB_DBUSER;
		if(!$dbpass) $dbhost=FRONKDB_DBPASS;
		if(!$dbname) $dbname=FRONKDB_DBNAME;
		
		return new FronkDB($dbhost,$dbuser,$dbpass,$dbname);
	}
	
	public static function redirect($mod=false,$action=false,$params=false,$anker=false) {
		//var_dump($mod);
		//var_dump($action);
    
    $log = mfLoghandler::singleton();
		
    if(MFUSEFANCYURLS && defined('MFFANCYBASEURL')) {
      // use fancy urls
      $url=MFFANCYBASEURL;
      if($mod) {
        $url.="/$mod";
        if($action) {
          $url.="/$action";
        }
      }
    } else {
      // no fancy urls
      if(!$mod) {
        $url="?";
      } elseif($mod) {
        $url="?action=$mod";
        if($action) {
          $url.="_$action";
        }
      }
    }
    /*
    if(is_array($params) && count($params)) {
      foreach($params as $k => $v) {
        $url.="&$k=$v";
      }
    }*/
    
    if($params) {

	    if(is_array($params) && count($params)) {
	      $url .= (MFUSEFANCYURLS) ? "/?" : "&";
				foreach($params as $k => $v) {
	        $v = urlencode($v);
	        
	        if($k) {
	          $k = urlencode($k);
	          $url .= "$k=$v&";
        	} else {
	          $url .= "$v&";
	        }
				}
	      
	      $url = preg_replace('/&$/', '', $url);
	    } else {
		    $url .= (MFUSEFANCYURLS) ? "/?" : "&";
		    $url .= $params;
	    }
    }
    if($anker) {  
      $url.="#$anker";  
    }

    $log->debug("Redirecting to $url");
		header("Location: $url");
		exit;
	}
  
  public static function getUrl($mod, $action=null, $param=null) {
		if(!$mod) {
			return "";
		}

    
    if(MFUSEFANCYURLS) {
      // use fancy urls
      $url=MFFANCYBASEURL;
      if($mod) {
        $url.="/$mod";
        if($action) {
          $url.="/$action";
        }
      }
      $url = preg_replace('#//#','/',$url);
    } else {
      // no fancy urls
      $url="?action=$mod";
      if($action) {
        $url.="_$action";
      }
    }
		if(is_array($param) && count($param)) {
      $url .= (MFUSEFANCYURLS) ? "/" : "&amp;";
      $param_qs = http_build_query($param);
			$url .= "$param_qs";
		}
		
		return $url;
	}
  
  public static function returnJson($data) {
    if(is_array($data)) {
      header("Content-Type: application/json");
      echo json_encode($data);
      exit;
    } else {
      throw new Exception("Data not an array");
    }
  }
  
  // Helper functions

    public static function dateToTimestamp($date) {
    $t = array(0,0,0);

    // extract day, month, year
    if (!preg_match('/^(\d{1,2})\.(\d{1,2})\.(\d{2,4})/',$date,$d)) {
      return false;
    }
    // extract time if available
    if (preg_match('/(\d\d):(\d\d):(\d\d)$/',$date,$t)) {
      if (!$t[3]) {
        $t[3] = 0;
      }
    }
  // make and return timestamp
    $ts = mktime($t[1],$t[2],$t[3],$d[2],$d[1],$d[3]);
    return $ts;
  }
  
  public static function dateToDB($date,$type='l') {
    // get timestamp
    $ts = self::dateToTimestamp($date);
    
    // only proceed if timestamp conversion was successful
    if(!$ts) {
      return false;
    }
    
    // return date and time if long type requested
    if($type = 'l') {
      $dbdate = date('Y-m-d H:i:s',$ts);
    } else {
      $dbdate = date('Y-m-d',$ts);
    }

    return $dbdate;
  }
  
}
