<?

class player_app {

	private $base_instance = NULL;

	public function __construct($base_instance) {
		$this->data = $data->fetch('player');
		$data->player_main_instance = $this->data;
		$this->data->statement = $data->statement;
		$this->is_choosing_screens = false;
		$this->global_pause_active = false;
		delete $this->tabs['init'];
		$this->base_instance = $base_instance;

		$data->main_player = $this->data;
		
		$this->data->last_id = function($v) {
			if($object->isset($v['id'])) {
				return $v['id'];
			}
			return $data->main_player->last_insert_id();
		};

		$init_string = 'CREATE TABLE IF NOT EXISTS status (
		video_path text,
		current_position double,
		current_time double,
		current_time_text text,
		current_position_text text,
		is_playing integer,
		template_id integer
		);
		CREATE TABLE IF NOT EXISTS status_sync (
		video_path text,
		current_position double,
		current_time double,
		current_time_text text,
		current_position_text text,
		is_playing integer,
		template_id integer
		);
		CREATE TABLE IF NOT EXISTS main_settings (
			property_name text,
			property_value text
		);
		CREATE TABLE IF NOT EXISTS history (
			id integer primary key autoincrement,
			filepath TEXT
		);
		CREATE TABLE IF NOT EXISTS display_settings (
			property_name text,
			property_value text,
			display_view text
		);
		';


		$init_tables = $object->strings->split($init_string, ';');
		foreach($init_tables as $init_table) {
			$this->data->execute($init_table, []);
		}
		$table_update = new table_structure_update($init_string, $this->data);

		$self = $this;

		$media->get_current_tab = function() {
			return $self->get_current_tab();
		};

		$this->display_settings = new display_settings($this->data);

		/*$object->destruct_tabs = function() {
			$self->close_all_tabs();
		};*/
	}

	public function enter_fullscreen($v=NULL) {
		$object->enter_fullscreen();
		return true;
	}

	public function start_ws_server($v) {
		$object->set_ws_server($v['ip'], $v['port'], function($status) {
			$object->send('app.ws.display_server_status(data)', ['data' => $status]);
		});
		return true;
	}

	public function reset_sync($v=NULL) {
		/*$this->current_tab->reset_sync();*/
		$status_values = $this->current_tab->status(true);
		return $status_values;
	}

	public function reload_app($v=NULL) {
		$this->close_all_tabs();
		$object->log('in reload app');
		$object->reload_app();
		return ['res' => true];
	}

	public function get_display_settings($v=NULL) {
		return $this->display_settings->get_settings($v);
	}

	public function set_display_setting($v=NULL) {
		return $this->display_settings->set_setting($v);
	}

	private $display_settings;

	public function add_new_window($v=NULL) {
		return $media->add_window();
	}

	public function get_status_from_path($path) {
		$query = 'SELECT * FROM status WHERE video_path = ?';
		$row = $this->data->get_row($query, 1);
		return $row;
	}

	public function get_main_settings($v=NULL) {
		$query = 'SELECT * FROM main_settings';
		$rows = $this->data->get_rows($query, []);
		foreach($rows as $row) {
			if($row['property_name'] == 'disable_subtitles_input') {
				if($row['property_value'] == true || $row['property_value'] == 1) {
					$object->set_app_property('disableSubtitles', true);
				} else {
					$object->set_app_property('disableSubtitles', false);
				}
			}
		}
		return $rows;
	}

	public function set_setting($values=NULL) {
		if($values['property_name'] == 'disable_subtitles_input') {
			if($values['property_value'] == true || $values['property_value'] == 1) {
				$object->set_app_property('disableSubtitles', true);
			} else {
				$object->set_app_property('disableSubtitles', false);
			}
		}
		$query = 'DELETE FROM main_settings WHERE property_name = ?';
		$this->data->execute($query, [$values['property_name']]);
		$insert = $this->data->statement->generate($values, 'main_settings');
		$this->data->_($insert, $values);
		return ['result' => 1];
	}

	private $tabs = [
		'init' => NULL
	];

	private $tab_index = 0;

	public function add_tab($v) {
		$media_tab = $media->add_tab(NULL);
		$media_tab->current_media = ['media_path' => NULL];
		$this->tab_index = $this->tab_index+1;
		$next_key = 'tab_'.$this->tab_index;
		$this->tabs[$next_key] = $media_tab;
		$self = $this;
		$media_tab->register_callback(function($par) {
			if($self->is_choosing_screens != false) {
				$self->switch_tabs(['tab_id' => $next_key]);
				$object->send('app.tabs.select_tab(data)', ['data' => $next_key]);
			}
		});
		$media_tab->register_callback(function($par) {
			if($self->is_choosing_screens != false) {
				$self->front($media_tab);
				return 1;
			}
			return 0;
		});
		$media_tab->register_callback(function($par) {
			$object->send('app.playlists.play(data)', ['data' => $next_key]);
		});
		$media_tab->register_callback(function($par) {
			$self->set_last_played();
			$self->report_duration($par); /*media_tab->get_duration()*/
		});
		return ['tab_id' => $next_key];
	}

	private $global_pause_active = NULL;

	public function toggle_global_pause($v) {
		if($this->global_pause_active) {
			$this->global_pause_active = false;
			return ['result' => 0];
		} else {
			$this->global_pause_active = true;
		}
		return ['result' => 1];
	}

	private $bounds = [];
	public function register_bounds($bounds) {
		$this->bounds = $bounds;
		$media->set_bounds($bounds);
	}
	
	private $current_tab = NULL;

	public function get_current_tab() {
		return $this->current_tab;
	}

	public function get_last_played($v=NULL) {
		$query = 'SELECT * FROM status WHERE template_id = ?';
		$rows = $this->data->get_rows($query, [$v['template_id']]);
		if($rows->length > 0) {
			$status_item = $rows[0];
			$this->play([
				'path' => $status_item['video_path'],
				'template_id' => $v['template_id'],
				'tab_id' => $v['tab_id'],
				'current_time' => $status_item['current_time']
			], false);
			return [
				'result' => true
			];
		}
		return ['result' => false];
	}

	public function has_media($v=NULL) {
		if($this->current_tab->current_media['media_path'] != NULL) {
			return ['result' => true];
		}
		return ['result' => false];
	}

	public function get_current_tab_time($v=NULL) {
		if($this->base_instance->indexing_in_progress) {
			return [
				'current_time' => 0,
				'total' => 0,
				'sync_status' => NULL
			];
		}
		$sync_status = ['playing' => 'not_playing'];
		if($this->current_tab != NULL) {
			$current_time = $this->current_tab->time();
			$total_time = $this->current_tab->total_time();
			if($this->current_tab->current_media['media_path'] != NULL) {
				$media_path = $this->current_tab->current_media['media_path'];
				$query = 'DELETE FROM status WHERE video_path = ?';
				$this->data->execute($query, [$media_path]);
				$values = [
					'video_path' => $media_path,
					'current_time' => $current_time
				];
				if($object->isset($this->current_tab->current_media['template_id'])) {
					$values['template_id'] = $this->current_tab->current_media['template_id'];
				}
				$insert = $this->data->statement->generate($values, 'status');
				$this->data->_($insert, $values);
				$sync_status = $this->save_status();
			}
			return [
				'total_time' => $total_time,
				'current_time' => $current_time,
				'sync_status' => $sync_status
			];
		}
		return [
			'current_time' => 0,
			'total' => 0,
			'sync_status' => $sync_status
		];
	}

	public function set_player_time($v=NULL) {
		if($this->current_tab != NULL) {
			$this->current_tab->set_time($v['time']);
		}
		return ['result' => 1];
	}

	public $is_choosing_screens = NULL;

	public function call_choose_screens($v) {
		return ['result' => 1];
	}

	public function choose_screens($v) {
		if($this->is_choosing_screens == 2) {
			return ['result' => -1];
		}
		$this->is_choosing_screens = 2;
		$root = $media->choose_screens();
		return ['result' => $root];
	}

	public function choose_screens_alt($v) {
		if($this->is_choosing_screens == 3) {
			return ['result' => -1];
		}
		$this->is_choosing_screens = 3;
		$media->choose_screens_alt($this->current_tab);
		return ['result' => 1];
	}

	public function pause($v) {
		$this->current_tab->pause();
	}

	public function pause_all($v=NULL) {
		foreach($this->tabs as $tab) {
			if($tab->is_playing()) {
				$tab->pause();
			}
		}
		return ['result' => 1];
	}

	public function front($next_tab) {
		$next_tab->front();
		foreach($this->tabs as $key => $other_tab) {
			if(!$object->equals($other_tab, $next_tab)) {
				$other_tab->back();
			}
		}
	}

	public function fill_view($v) {
		if($this->is_choosing_screens != false && $this->current_tab != NULL) {
			$this->is_choosing_screens = false;
			$this->front($this->current_tab);
			$this->current_tab->fill_view();
		}
		return ['result' => 1];
	}

	public function to_window($v) {
		$next_tab = $this->tabs[$v['tab_id']];
		$next_tab->is_extended = true;
		$this->current_tab = NULL;
		$next_tab->extend_to_window();
	}

	public function switch_tabs($v) {
		/*if($this->base_instance->indexing_in_progress) {
			return ['result' => 0];
		}*/
		$next_tab = $this->tabs[$v['tab_id']];
		if(!$object->isset($next_tab)) {
			return ['result' => '-1'];
		}
		if($this->is_choosing_screens != false) {
			$this->is_choosing_screens = false;
			$this->front($next_tab);
			$next_tab->fill_view();

			if($this->global_pause_active) {
				if($this->current_tab->is_playing()) {
					$this->current_tab->pause();
				}
				if(!$next_tab->is_playing()) {
					$next_tab->pause();
				}
			}
			
			$this->current_tab = $next_tab;
			return ['result' => 1];
		}
		if($this->current_tab != NULL) {
			if($object->equals($next_tab, $this->current_tab)) {
				return ['result' => 0];
			} else {
				$this->front($next_tab);
				$next_tab->fade_switch($this->current_tab);

				if($this->global_pause_active) {
					if($this->current_tab->is_playing()) {
						$this->current_tab->pause();
					}
					if(!$next_tab->is_playing()) {
						$next_tab->pause();
					}
				}
			}	
		} else {
			$next_tab->fade_in();
		}
		$this->current_tab = $next_tab;

		return ['result' => 1];
	}

	public function close_all_tabs() {
		foreach($object->values($this->tabs) as $tab) {
			$tab->close();
		}
	}

	public function close_tab($v) {
		$tab_id = $v['tab_id'];
		$this->tabs[$tab_id]->close();
		delete $this->tabs[$tab_id];
		return ['result' => 1];
	}

	public function toggle_media($v=NULL) {
		$set_tab = $this->current_tab;
		if($set_tab != NULL && $object->isset($set_tab->current_media)) {
			$media_path = $set_tab->current_media['media_path'];
			if($media_path != NULL) {
				$this->base_instance->apps['tv']->toggle_episode_by_path($media_path);
				$this->base_instance->apps['cinema']->toggle_movie_by_path($media_path);
			}
		}
		return ['result' => 1];
	}

	public function delete_watch_log_item($v) {
		$set_tab = $this->current_tab;

		

		$query = 'SELECT * FROM episodes WHERE path = ?';
		$episodes = $data->tv_main_instance->get_rows($query, [$set_tab->current_media['media_path']]);
		if($episodes->length > 0) {
		} else {
			$query = 'SELECT * FROM movies WHERE filepath = ?';
			$movies = $data->cinema_main_instance->get_rows($query, [$set_tab->current_media['media_path']]);
		}

	}


	public function set_audio_adjustment_level($v=NULL) {
		$set_tab = $this->current_tab;

		if($set_tab->current_media['media_path'] != NULL) {
			$query = 'SELECT * FROM episodes WHERE path = ?';
			$episodes = $data->tv_main_instance->get_rows($query, [$set_tab->current_media['media_path']]);
			if($episodes->length > 0) {
				$id = $episodes[0]['id'];
				$insert_data = [
					'id' => $id,
					'adjustment_level' => $v['adjustment_level']
				];
				$insert = $this->data->statement->generate($insert_data, 'episodes');
				$data->tv_main_instance->_($insert, $insert_data);

				return ['result' => 1];
			} else {
				$query = 'SELECT * FROM movies WHERE filepath = ?';
				$movies = $data->cinema_main_instance->get_rows($query, [$set_tab->current_media['media_path']]);
				if($movies->length > 0) {					
					$id = $movies[0]['id'];
					$insert_data = [
						'id' => $id,
						'adjustment_level' => $v['adjustment_level']
					];
					$insert = $this->data->statement->generate($insert_data, 'movies');
					$data->cinema_main_instance->_($insert, $insert_data);

					return ['result' => 1];
				}
			}
		}
		return ['result' => false];
	}

	public function play($v, $log=true) {
		if($this->base_instance->indexing_in_progress) {
			return ['result' => 0];
		}
		$set_tab = $this->current_tab;
		if($object->isset($v['tab_id'])) {
			$set_tab = $this->tabs[$v['tab_id']];
		}
		if($set_tab->current_media['media_path'] != NULL) {
			$query = 'DELETE FROM status WHERE video_path = ?';
			$this->data->execute($query, [$set_tab->current_media['media_path']]);
		}
		$set_tab->play($v['path']);
		$set_tab->current_media['media_path'] = $v['path'];
		if($object->isset($v['template_id'])) {
			$query = 'DELETE FROM status WHERE template_id = ?';
			$this->data->execute($query, [$v['template_id']]);
			$set_tab->current_media['template_id'] = $v['template_id'];
		}
		if($object->isset($v['current_time'])) {
			$set_tab->set_time($v['current_time'], true);
		} else {
			/*disregard previous status*/
			$query = 'SELECT * FROM status WHERE video_path = ?';
			$status = $this->data->get_rows($query, [$v['path']]);
			if($status->length > 0) {
				$set_tab->set_time($status[0]['current_time'], true);
			}
		}
		if($object->isset($v['log']) && $log) {
			$log = $v['log'];
		}
		if($log) {
			$episode = $this->base_instance->apps['tv']->add_path_to_log(['path' => $v['path']]);
			
			/*if($episode['result']) {
				$adjustment_level = $episode['row']['adjustment_level'];
				if($adjustment_level != NULL && $adjustment_level != '') {
					$object->send('app.controls.set_volume(adjustment)', ['adjustment' => $adjustment_level]);	
				}
			}*/
		}
		$this->set_adjustment_level($v['path']);
		

		$history_values = [
			'filepath' => $v['path']
		];
		$insert = $this->data->statement->generate($history_values, 'history');
		$this->data->_($insert, $history_values);
		return ['result' => 1];
	}

	public function set_last_played() {
		if($object->isset($this->current_tab['id_values'])) {
			$current_id = $this->current_tab['id_values']['id'];

			if($this->current_tab['id_values']['type'] == 'episode') {
				$query = 'UPDATE episodes SET lastplayed = CURRENT_TIMESTAMP WHERE id = ?';
				$data->tv_main_instance->execute($query, [$current_id]);
			} else if($this->current_tab['id_values']['type'] == 'movie') {
				$query = 'UPDATE movies SET lastplayed = CURRENT_TIMESTAMP WHERE id = ?';
				$data->cinema_main_instance->execute($query, [$current_id]);
			}
		}
	}

	public function report_duration($duration) {
		if($object->isset($this->current_tab['id_values']) && $this->current_tab['id_values']['duration'] == NULL) {
			$current_id = $this->current_tab['id_values']['id'];
			$v = [
				'id' => $current_id,
				'duration' => $duration
			];
			if($this->current_tab['id_values']['type'] == 'episode') {
				$insert = $this->data->statement->generate($v, 'episodes');
				$data->tv_main_instance->_($insert, $v);
			} else if($this->current_tab['id_values']['type'] == 'movie') {
				$insert = $this->data->statement->generate($v, 'movies');
				$data->cinema_main_instance->_($insert, $v);
			}
		}
	}

	/*private function get_adjustment_level_values($path, $tv_show_id) {
		$query = 'SELECT * FROM episodes WHERE tv_show_id = ?';
		$episodes = 
	}*/

	private function set_adjustment_level($path) {
		$path_components = $files->path_components($path);
		if($path_components->length > 2) {
			$object->splice($path_components, 0, 1);
			$object->splice($path_components, $path_components->length-1, 1);
		}
		$set_path = '/'.$object->strings->join($path_components, '/').'%';
		$query = 'SELECT * FROM episodes WHERE path = ?';
		$episode = $data->tv_main_instance->get_row($query, [$path]);
		$query = 'SELECT * FROM episodes WHERE path LIKE ? AND (max_audio_level IS NOT NULL AND audio_level IS NOT NULL)';
		$levels_item = $data->tv_main_instance->get_row($query, [$set_path]);
		if($episode != NULL) {
			/*$episode = $episodes[0];*/
			$this->current_tab['id_values'] = ['type' => 'episode', 'id' => $episode['id'], 'duration' => $episode['duration']];

			$adjustment_level = $episode['adjustment_level'];
			if($adjustment_level != NULL && $adjustment_level != '') {
				$object->send('app.controls.set_volume(adjustment)', ['adjustment' => $adjustment_level]);	
			} else if($levels_item != NULL) {
				$object->send('app.controls.set_volume(adjustment)', [
					'adjustment' => [
						'adjustment' => $adjustment_level, 
						'max_audio_level' => $levels_item['max_audio_level'], 
						'audio_level' => $levels_item['audio_level']
					]
				]);
			}
		} else {
			$query = 'SELECT * FROM movies WHERE filepath = ?';
			$movies = $data->cinema_main_instance->get_rows($query, [$path]);
			if($movies->length > 0) {
				$episode = $movies[0];
				$this->current_tab['id_values'] = ['type' => 'movie', 'id' => $episode['id'], 'duration' => $episode['duration']];
				$adjustment_level = $episode['adjustment_level'];
				if($adjustment_level != NULL && $adjustment_level != '') {
					$object->send('app.controls.set_volume(adjustment)', ['adjustment' => $adjustment_level]);	
				}
			}
		}
	}

	private $external_db = NULL;

	public function fetch_external_db($v) {
		$this->external_db = $data->fetchfile($v['path']);
		return ['result' => 1];
	}

	public function get_status($v) {
		$query = 'SELECT * FROM status_sync';
		$rows = $this->external_db->get_rows($query, []);
		if($rows->length > 0) {
			$status_value = $rows[0];
			$this->current_tab->status_value($status_value);
			return $status_value;
		}
		return ['result' => 1];
	}

	public function set_sync_status($v) {
		if($this->current_tab != NULL) {
			$this->current_tab->status_value($v['sync_status']);
		}
		return ['result' => 1];
	}

	public function is_playing($v) {
		return ['result' => $this->current_tab->is_playing()];
	}

	public function toggle_audio($v) {
		$this->current_tab->toggle_audio();
	}

	public function set_volume($v) {
		$this->current_tab->set_volume($v['volume']);
	}

	public function get_volume($v) {
		return ['volume' => $this->current_tab->get_volume()];
	}

	public function save_status($v) {
		if($this->base_instance->indexing_in_progress) {
			return ['result' => 'not_playing'];
		}
		$status_values = $this->current_tab->status(false);
		/*if($object->isset($status_values['is_playing'])) {*/
		if($this->current_tab->is_playing()) {
			$query = 'DELETE FROM status_sync';
			$this->data->execute($query, []);
			$insert = $this->data->statement->generate($status_values, 'status_sync');
			$this->data->_($insert, $status_values);
			return $status_values;
		}
		return ['result' => 'not_playing'];
	}

	public function get_history($v=NULL) {
		$query = 'SELECT * FROM history ORDER BY id DESC LIMIT 100';
		return $this->data->get_rows($query, []);
	}
}

?>