<?php

class Application_Model_LiveLog
{

    public static function GetLiveShowDuration($p_keepData=false)
    {
        try {

            $sql = "SELECT * FROM CC_LIVE_LOG"
            ." WHERE state = :state"
            ." and (start_time >= (now() - INTERVAL '1 day'))"
            ." ORDER BY id";
            $rows = Application_Common_Database::prepareAndExecute($sql, array(':state'=>'L'),
                Application_Common_Database::ALL);

            /* Check if last log has end time.
             * If not, set end time to current time
             */
            if ($rows != null) {
                $last_row = self::UpdateLastLogEndTime(array_pop($rows));
                array_push($rows, $last_row);
                $skip = false;
            } else {
                $sql = "SELECT * FROM CC_LIVE_LOG"
                    ." WHERE state = :state"
                    ." ORDER BY id";
                $rows = Application_Common_Database::prepareAndExecute($sql, array(':state'=>'L'),
                    Application_Common_Database::ALL);

                if ($rows != null) {
                    $last_row = self::UpdateLastLogEndTime(array_pop($rows));
                    array_push($rows, $last_row);
                    foreach ($rows as $row) {
                        $sql_delete = "DELETE FROM CC_LIVE_LOG"
                                    ." WHERE id = :id";
                        Application_Common_Database::prepareAndExecute($sql_delete, array(':id'=>$row['id']),
                            Application_Common_Database::EXECUTE);
                    }
                }
                $skip = true;
            }

            $hours = 0;
            $minutes = 0;
            $seconds = 0;

            if (!$skip) {
                foreach ($rows as $row) {
                    $end = new DateTime($row['end_time']);
                    $start = new DateTime($row['start_time']);
                    $duration = $start->diff($end);
                    $duration = $duration->format("%H:%i:%s");
                    $intervals = explode(":", $duration);
                    for ($i = 0; $i < sizeof($intervals); $i++) {
                        if (!isset($intervals[$i])) {
                            $intervals[$i] = 0;
                        }
                    }

                    // Trim milliseconds (DateInterval does not support)
                    $sec = explode(".", $intervals[2]);
                    if (isset($sec[0])) {
                        $intervals[2] = $sec[0];
                    }

                    $seconds += $intervals[2];
                    if ($seconds / 60 >= 1) {
                        $minutes += 1;
                        $seconds -= 60;
                    }

                    $minutes += $intervals[1];
                    if ($minutes / 60 >= 1) {
                        $hours += 1;
                        $minutes -= 60;
                    }

                    $hours += $intervals[0];

                    if (!$p_keepData) {
                        // Delete data we just used to start a new log history
                        $sql_delete = "DELETE FROM CC_LIVE_LOG"
                        ." WHERE id = :id";
                        Application_Common_Database::prepareAndExecute($sql_delete, array(':id'=>$row['id']),
                            Application_Common_Database::EXECUTE);
                    }
                }
                //Trim milliseconds
                $seconds = explode(".", $seconds);
                if (isset($seconds[0])) {
                    $minutes = (double) (($hours*60)+$minutes . "." . $seconds[0]);
                } else {
                    $minutes = (double) (($hours*60)+$minutes);
                }
            }

            return $minutes;
        } catch (Exception $e) {
            header('HTTP/1.0 503 Service Unavailable');
            Logging::info("GetLiveShowDuration - Could not connect to database.");
            exit;
        }
    }

    public static function GetScheduledDuration($p_keepData=false)
    {
        try {

            $sql_get_logs = "SELECT * FROM CC_LIVE_LOG"
            ." WHERE state = :state"
            ." and (start_time >= (now() - INTERVAL '1 day'))"
            ." ORDER BY id";

            $rows = Application_Common_Database::prepareAndExecute($sql_get_logs, array(':state'=>'S'),
                Application_Common_Database::ALL);

            /* Check if last log has end time.
             * If not, set end time to current time
             */
            if ($rows != null) {
                $last_row = self::UpdateLastLogEndTime(array_pop($rows));
                array_push($rows, $last_row);
                $skip = false;
            } else {
                $sql = "SELECT * FROM CC_LIVE_LOG"
                    ." WHERE state = :state"
                    ." ORDER BY id";
                    $rows = Application_Common_Database::prepareAndExecute($sql, array(':state'=>'S'),
                        Application_Common_Database::ALL);

                if ($rows != null) {
                    $last_row = self::UpdateLastLogEndTime(array_pop($rows));
                    array_push($rows, $last_row);
                    foreach ($rows as $row) {
                        $sql_delete = "DELETE FROM CC_LIVE_LOG"
                                    ." WHERE id = :id";
                        Application_Common_Database::prepareAndExecute($sql_delete, array(':id'=>$row['id']),
                            Application_Common_Database::EXECUTE);
                    }
                }
                $skip = true;
            }

            $hours = 0;
            $minutes = 0;
            $seconds = 0;

            if (!$skip) {
                /* Get all shows and tracks from cc_schedule that played
                 * during a scheduled state
                 */
                foreach ($rows as $row) {
                    $sql_get_tracks = "SELECT * FROM cc_schedule"
                    ." WHERE starts >= :starts1"
                    ." AND starts < :starts2"
                    ." AND file_id IS NOT NULL"
                    ." AND media_item_played IS TRUE";
                    $params = array(
                        ':starts1'=>$row['start_time'],
                        ':starts2'=>$row['end_time']
                    );
                    $tracks = Application_Common_Database::prepareAndExecute($sql_get_tracks, $params,
                        Application_Common_Database::ALL);

                    foreach ($tracks as $track) {
                        if ($track['ends'] > $row['end_time']) {
                            $scheduled_ends = new DateTime($row['end_time']);
                            $track_ends = new DateTime($track['ends']);
                            $extra_time = $scheduled_ends->diff($track_ends);

                            /* Get difference between clip_length
                             * and the extra time. We need to subtract
                             * this difference from the track's
                             * clip length.
                             */
                            $clip_length = $track['clip_length'];
                            //Convert clip_length into seconds
                            $clip_length_intervals = explode(":", $clip_length);
                            for ($i = 0; $i < sizeof($clip_length_intervals); $i++) {
                                if (!isset($clip_length_intervals[$i])) {
                                    $clip_length_intervals[$i] = 0;
                                }
                            }
                            $clip_length_seconds = $clip_length_intervals[0]*3600 + $clip_length_intervals[1]*60 + $clip_length_intervals[2];

                            $extra_time = $extra_time->format("%H:%i:%s");
                            //Convert extra_time into seconds;
                            $extra_time_intervals = explode(":", $extra_time);
                            for ($i = 0; $i < sizeof($extra_time_intervals); $i++) {
                                if (!isset($extra_time_intervals[$i])) {
                                    $extra_time_intervals[$i] = 0;
                                }
                            }
                            $extra_time_seconds = $extra_time_intervals[0]*3600 + $extra_time_intervals[1]*60 + $extra_time_intervals[2];

                            $clip_length_seconds -= $extra_time_seconds;

                            //Convert new clip_length into "H-i-s" format
                            $clip_length_arr = array();
                            if ($clip_length_seconds / 3600 >= 1) {
                                array_push($clip_length_arr, str_pad(floor($clip_length_seconds / 3600), 2, "0", STR_PAD_LEFT));
                                $clip_length_seconds -= floor($clip_length_seconds / 3600);
                            } else {
                                array_push($clip_length_arr, "00");
                            }
                            if ($clip_length_seconds / 60 >= 1) {
                                array_push($clip_length_arr, str_pad(floor($clip_length_seconds / 60), 2, "0", STR_PAD_LEFT));
                                $clip_length_seconds -= floor($clip_length_seconds / 60);
                            } else {
                                array_push($clip_length_arr, "00");
                            }

                            array_push($clip_length_arr, str_pad($clip_length_seconds, 2, "0", STR_PAD_LEFT));
                            $clip_length = implode(":", $clip_length_arr);
                        } else {
                            $clip_length = $track['clip_length'];
                        }

                        $intervals = explode(":", $clip_length);
                        for ($i = 0; $i < sizeof($intervals); $i++) {
                            if (!isset($intervals[$i])) {
                                $intervals[$i] = 0;
                            }
                        }
                        // Trim milliseconds (DateInteral does not support)
                        $sec = explode(".", $intervals[2]);
                        if (isset($sec[0])) {
                            $intervals[2] = $sec[0];
                        }

                        $seconds += $intervals[2];
                        if ($seconds / 60 >= 1) {
                            $minutes += 1;
                            $seconds -= 60;
                        }

                        $minutes += $intervals[1];
                        if ($minutes / 60 >= 1) {
                            $hours += 1;
                            $minutes -= 60;
                        }

                        $hours += $intervals[0];
                    }

                    if (!$p_keepData) {
                        //Delete row because we do not need data anymore
                        $sql_delete = "DELETE FROM CC_LIVE_LOG"
                                    ." WHERE id = :id";
                        Application_Common_Database::prepareAndExecute($sql_delete, array(':id'=>$row['id']),
                            Application_Common_Database::EXECUTE);
                    }
                }


                $seconds = explode(".", $seconds);
                if (isset($seconds[0])) {
                    $minutes = (double) (($hours*60)+$minutes . "." . $seconds[0]);
                } else {
                    $minutes = (double) (($hours*60)+$minutes);
                }
            }

            return $minutes;
        } catch (Exception $e) {
            header('HTTP/1.0 503 Service Unavailable');
            Logging::info("GetScheduledDuration - Could not connect to database.");
            exit;
        }
    }

    public static function UpdateLastLogEndTime($log)
    {
        if ($log['end_time'] == null) {
            $current_time = new DateTime("now", new DateTimeZone('UTC'));
            $log['end_time'] = $current_time;
            $log['end_time'] = $log['end_time']->format("Y-m-d H:i:s");
            self::SetEndTime($log['state'], $current_time, true);
            self::SetNewLogTime($log['state'], $current_time);
        }

        return $log;
    }

    public static function SetNewLogTime($state, $dateTime)
    {
        try {

            $scheduled = Application_Model_Preference::GetSourceSwitchStatus('scheduled_play');
            if ($state == 'L' && $scheduled == 'on') {
                self::SetEndTime('S', $dateTime);
            }

            /* Only insert new state if last log
             * has ended
             */
            $sql_select = "SELECT max(id) from CC_LIVE_LOG"
            ." WHERE (state= :state1 and end_time is NULL) or (state= :state2 and end_time is NULL)";
            $params = array(
                ":state1"=> 'L',
                ":state2"=> 'S'
            );
            $id = Application_Common_Database::prepareAndExecute($sql_select, $params,
                Application_Common_Database::COLUMN);

            if ($id == null) {
                $sql_insert = "INSERT INTO CC_LIVE_LOG (state, start_time)"
                ." VALUES (:state, :start)";
                $params = array(
                    ':state'=>$state,
                    ':start'=>$dateTime->format("Y-m-d H:i:s")
                );
                Application_Common_Database::prepareAndExecute($sql_insert, $params,
                    Application_Common_Database::EXECUTE);
                if ($state == "S") {
                    // if scheduled play source is getting broadcasted
                    Application_Model_Schedule::UpdateBrodcastedStatus($dateTime, 1);
                }
            }

        } catch (Exception $e) {
            header('HTTP/1.0 503 Service Unavailable');
            Logging::info("SetNewLogTime - Could not connect to database.");
            exit;
        }
    }

    public static function SetEndTime($state, $dateTime, $override=false)
    {
        try {
            $dj_live = Application_Model_Preference::GetSourceSwitchStatus('live_dj');
            $master_live = Application_Model_Preference::GetSourceSwitchStatus('master_dj');

            if (($dj_live=='off' && $master_live=='off') || $state == 'S' || $override) {
                $sql = "SELECT id, state from cc_live_log"
                ." where id in (select max(id) from cc_live_log)";
                $row = Application_Common_Database::prepareAndExecute($sql, array(),
                    Application_Common_Database::SINGLE);

                /* Only set end time if state recevied ($state)
                 * is the last row in cc_live_log
                 */
                if ($row['state'] == $state) {
                    $update_sql = "UPDATE CC_LIVE_LOG"
                    ." SET end_time = :end"
                    ." WHERE id = :id";
                    $params = array(
                        ':end'=>$dateTime->format("Y-m-d H:i:s"),
                        ':id'=>$row['id']
                    );
                    Application_Common_Database::prepareAndExecute($update_sql, $params,
                        Application_Common_Database::EXECUTE);
                }

                //If live broadcasting is off, turn scheduled play on
                $scheduled = Application_Model_Preference::GetSourceSwitchStatus('scheduled_play');
                if ($state == 'L' && $scheduled=='on' && !$override) {
                    self::SetNewLogTime('S', $dateTime);
                }
            }

        } catch (Exception $e) {
            header('HTTP/1.0 503 Service Unavailable');
            Logging::info("SetEndTime - Could not connect to database.");
            exit;
        }
    }

}
