<?php
/**
 * @category 	Atmail
 * @package 	Models
 * @subpackage	Graph
 * @copyright 	Copyright (c) 2009-2011 ATMAIL. All rights reserved
 * @license 	See http://atmail.com/license.php for license agreement
 * @author		Ben Duncan ben@staff.atmail.com
 * @author		Atmail (http://atmail.com)
 */
 
class graph
{	
	private $_session;
	private $_account;
	private $_tableNames;
	private $_namespaceName = 'admin';
		
	public function __construct()
	{

		$this->dbAdapter = Zend_Registry::get('dbAdapter');
		//$this->dbAdapter->getProfiler()->setEnabled(true);
	}

	public function getLog($timeframe, $log, $account='', $type='', $domains = array())
	{
		$points = $names = array();
	    $extra = '';

		if(empty($domains[0]))
			$domains[] = "";

		// First, check the cache
		if(($graphCache = Atmail_Cache::fetch(Atmail_Cache::TYPE_GRAPH, $timeframe . $log . $account . $type . md5(implode($domains)) . $domains)) !== false)
		{
			
			return $graphCache;
			
		}

		if (strlen($account) > 0)
		{
			
			$extra = "and Account = " . $this->dbAdapter->quote($account);
			
		}
		
		if (!empty($type))
		{
			
			$extra .= " and LogType = " . $this->dbAdapter->quote($type);
			
		}

		// Support Subadmin logins, only graph the selected domain
		if ( !empty($domains[0]) )
		{
			$extra .= " and ( ";
			$where = array();
			foreach($domains as $domain) {
				$where[] = "Account like " . $this->dbAdapter->quote("%@" . $domain);
			}
			$extra .= implode(" or ", $where);
			$extra .= " ) ";
			
		}
		
		if ($timeframe == 'live')
		{
		    $time = time();

		    $minutes = 14;
	        $last = 0;

		    for ($t=0; $t<15; $t++)
			{
				$end = $time - ($last * 60);
				$start = $time - ($t * 60);

				$last = $t;

				// check for Users stats
				if ($log == 'Users') {
				    $query = "select count(id) from Users where UNIX_TIMESTAMP(DateCreate) > '$start' and UNIX_TIMESTAMP(DateCreate) < '$end' $extra";
	                $value = $this->dbAdapter->fetchAll($query);
				} else {
				    $value = $this->dbAdapter->fetchAll("select count(id) from {$log} where UNIX_TIMESTAMP(LogDate) > '$start' and UNIX_TIMESTAMP(LogDate) < '$end' $extra");
				}
				if (!$value) $value = 0;

				$points[] = "$minutes,$value";
				$minutes--;
				$names[] = $t;
				//$names = array_reverse($names);
			}
		}
		elseif ($timeframe == 'day')
		{
			$hours = 23;
			for ($t=0; $t<24; $t++)
			{
				list($hour, $fulltime) = $this->calc_minutes(time(), $t);

				$start = $hour . "00";
				$end = $hour . "59";

				array_push($names, $fulltime);

				$end = $t + 1;
				
				// check for Users stats
				if ($log == 'Users') 
				{
				
				    $query = "select count(id) as total from Users where DateCreate > '$start' and DateCreate < '$end' $extra";
	                $value = $this->dbAdapter->fetchAll($query);
				
				}
				else
				{
				
				    $value = $this->dbAdapter->fetchAll("select count(id) as total from {$log} where LogDate > DATE_SUB(NOW(), INTERVAL $end HOUR) and LogDate < DATE_SUB(NOW(), INTERVAL $t HOUR) $extra");
				
				}
				if( !$value )
				{
				
					$value = 0;
					
				}
				
				$t2 = $t;//+1;
				$ts = strtotime("-$t2 hour") * 1000;
				$ts = $ts + (date('Z') * 1000);
				
				$points[] = array((string)$ts, (string)$value[0]['total']);
				$hours--;
				//$names = array_reverse($names);
			}
		}
		elseif ($timeframe == 'week')
		{
			$daysleft = 6;
            
			for ($day=0; $day<7; $day++)
			{
				list($weekday, $dayname)= $this->calc_week(time(), $day);
				array_push($names, $dayname);

				$dayback = $day-1;

				// check for Users stats
				if ($log == 'Users') {
	                 if ($day == 0) {
				        $value = $this->dbAdapter->fetchAll("select count(id) as total from Users where DateCreate > DATE_SUB(CURDATE(), INTERVAL 0 DAY) and DateCreate < NOW() $extra");
				    } else {
				        $value = $this->dbAdapter->fetchAll("select count(id) as total from Users where DateCreate > DATE_SUB(CURDATE(), INTERVAL $day DAY) and DateCreate < DATE_SUB(CURDATE(), INTERVAL $dayback DAY) $extra");
				    }
				} else  {
				    if ($day == 0)
				    {
				        $value = $this->dbAdapter->fetchAll("select count(id) as total from $log where LogDate > DATE_SUB(CURDATE(), INTERVAL 0 DAY) and LogDate < NOW() $extra");
				    }
				    else
				    {
				        $value = $this->dbAdapter->fetchAll("select count(id) as total from $log where LogDate > DATE_SUB(CURDATE(), INTERVAL $day DAY) and LogDate < DATE_SUB(CURDATE(), INTERVAL $dayback DAY) $extra");
				    }
				}

				if (!$value) $value = 0;

				$ts = strtotime("-$day day") * 1000;
				$ts = $ts + (date('Z') * 1000);
				
				$points[] = array((string)$ts, (string)$value[0]['total']);
				$daysleft--;
			}
		}
		elseif ($timeframe == 'month')
		{
			$daysleft = 29;
            
			for ($day=0; $day<30; $day++)
			{
				list($weekday, $dayname)= $this->calc_week(time(), $day);
				array_push($names, $dayname);

				$dayback = $day-1;

				// check for Users stats
				if ($log == 'Users') {
	                 if ($day == 0) {
				        $value = $this->dbAdapter->fetchAll("select count(id) as total from Users where DateCreate > DATE_SUB(CURDATE(), INTERVAL 0 DAY) and DateCreate < NOW() $extra");
				    } else {
				        $value = $this->dbAdapter->fetchAll("select count(id) as total from Users where DateCreate > DATE_SUB(CURDATE(), INTERVAL $day DAY) and DateCreate < DATE_SUB(CURDATE(), INTERVAL $dayback DAY) $extra");
				    }
				} else  {
				    if ($day == 0)
				    {
				        $value = $this->dbAdapter->fetchAll("select count(id) as total from $log where LogDate > DATE_SUB(CURDATE(), INTERVAL 0 DAY) and LogDate < NOW() $extra");
				    }
				    else
				    {
				        $value = $this->dbAdapter->fetchAll("select count(id) as total from $log where LogDate > DATE_SUB(CURDATE(), INTERVAL $day DAY) and LogDate < DATE_SUB(CURDATE(), INTERVAL $dayback DAY) $extra");
				    }
				}

				if (!$value) $value = 0;

				$ts = strtotime("-$day day") * 1000;
				$ts = $ts + (date('Z') * 1000);
				
				$points[] = array((string)$ts, (string)$value[0]['total']);
				$daysleft--;
			}
		}		
		elseif ($timeframe == 'year')
		{
			$months = 11;
			for ($month=0; $month<12; $month++)
			{
				list($yearvalue, $monthname)= $this->calc_year(time(), $month);

				array_push($names, $monthname);
				$monthback = $month-1;

				$yearback = $this->sql_date_shift(time(), $monthback);

	            if ($log == 'Users') {
	                 if ($month == 0) {
	                     $query = "SELECT COUNT(id) as total
	                               FROM Users
	                               WHERE DateCreate > DATE_SUB(CURDATE(), INTERVAL 0 MONTH)
	                               AND DateCreate < NOW() $extra";

				        $value = $this->dbAdapter->fetchAll($query);
				    } else {
				        $query = "SELECT COUNT(id) as total
				                  FROM Users
				                  WHERE DateCreate > DATE_SUB(CURDATE(), INTERVAL $month MONTH)
				                  AND DateCreate < DATE_SUB(CURDATE(), INTERVAL $monthback MONTH) $extra";

				        $value = $this->dbAdapter->fetchAll($query);
				    }
	            } else {
				   $value = $this->dbAdapter->fetchAll("SELECT COUNT(id) as total
				                            FROM $log
				                            WHERE LogDate > DATE_SUB(CURDATE(), INTERVAL $month MONTH)
				                            AND LogDate < DATE_SUB(CURDATE(), INTERVAL $monthback MONTH) $extra");
	            }

				if (!$value) $value = 0;

				$points[] = array((string)strtotime("-$month month") * 1000, (string)$value[0]['total']);
				$months--;
			}
		}

		$names = array_reverse($names);

		// Save the cache
		Atmail_Cache::store(Atmail_Cache::TYPE_GRAPH, $timeframe . $log . $account . $type . md5(implode($domains)) . $domains, $points);

		return $points;
	}

	// Get a date with the year/month/day, mySQL timestamp() style
	public function get_date($t=null)
	{
		if (!$t)
			$t = time();

	    $year = date('y', $t);
	    if ($year < 10)
			$year = "0$year";

	    $month = date('m', $t);
	    if ($month < 10)
			$month = "0$month";

	    $day = date('d', $t);
	    if ($day < 10)
			$day = "0$day";

	    $time = "$year$month$day";

	    return $time;
	}

	# Get a week, mySQL timestamp() style
	public function calc_week($time, $num)
	{
	    $days = 86400 * $num;

	    $time = $time - $days;

	    $newtime = strftime("%D", $time);
		$day = strftime("%A", $time);

	    preg_match('/(\d\d)\/(\d\d)\/(\d\d)/', $newtime, $m);
	    $newtime = "$m[3]$m[1]$m[2]";
	    return array($newtime, $day);
	}

	# Get a year/month, mySQL timestamp() style
	public function calc_year($time, $num)
	{
		$seconds = strtotime("-$num months", $time);

		$newtime = strftime("%D", $seconds);
		$monthname = strftime("%b %y", $seconds);

	    preg_match('/(\d\d)\/(\d\d)\/(\d\d)/', $newtime, $m);
	    $newtime = "$m[3]$m[1]31000000";

	    return array($newtime, $monthname);
	}

	# Get a year/month, mySQL timestamp() style
	public function calc_minutes($time, $num)
	{
		$t = strtotime("-$num hours", $time);

	    $year = strftime( "%y", $t);
	    if (strlen($year) < 2)
			$year = "0$year";

	    $month = date('m', $t);
	    if (strlen($month) < 2)
			$month = "0$month";

	    $day = strftime("%d", $t);
	    if (strlen($day) < 2)
			$day = "0$day";

		$time = strftime("%R", $t);
	    if (strlen($time) < 2)
			$time = "0$time";
		$time = preg_replace('/:\d\d$/', '', $time);

	    $fulltime = "$year$month$day$time";

	    return array($fulltime, "$time");
	}
	
	/**
	 * Calculate and convert datetime shift into sql format
	 *
	 * @param date/time $date current value
	 * @param string $shift time shift interval
	 * @return string
	 */
	public function sql_date_shift($date, $shift)
	{
	    $new_date = date("Y-m-d H:i:s" , strtotime($shift, strtotime($date)));
	    return  $new_date;
	}	
}
