<?

class cinema_app {

	private $data = NULL;

	public $base_instance = NULL;

	public function __construct($base_instance) {
		$this->base_instance = $base_instance;
		$this->data = $data->fetch('cinema');
		$data->cinema_main_instance = $this->data;
		$this->data->statement = $data->statement;

		$this->data->last_id = function($v) {
			if($object->isset($v['id'])) {
				return $v['id'];
			}
			return $data->cinema_main_instance->last_insert_id();
		};
/*CREATE TABLE IF NOT EXISTS metadata (
			movie_id integer,
			duration text,
			productioncompany text,
			director text,
			writer text,
			actor text,
			genre text,
			colortags text,
			tags text,
			series text,
			season integer,
			date datetime,
			lastplayed datetime,
			playcount integer

	
productioncompany text,
director text,
writer text,
actor text,
colortags text,
tags text,
series text,
season integer,
date datetime,

		);*/
		$init_string = '
CREATE TABLE IF NOT EXISTS folders (
id INTEGER primary key AUTOINCREMENT,
name text,
songs_order TEXT
);
CREATE TABLE IF NOT EXISTS movie_folder (
id INTEGER primary key AUTOINCREMENT,
movie_id INTEGER,
folder_id INTEGER
);
CREATE TABLE IF NOT EXISTS preferences (
id INTEGER primary key AUTOINCREMENT,
tv_shows_location TEXT,
movies_location TEXT
);
CREATE TABLE IF NOT EXISTS movies (
id INTEGER primary key AUTOINCREMENT,
filename TEXT,
filepath TEXT,
created DATETIME DEFAULT current_timestamp,
favorite BOOLEAN DEFAULT 0,
checked BOOLEAN DEFAULT 1,
oldpath TEXT,
deleted BOOLEAN default 0,
year DATETIME,
genre integer,
filesize TEXT,
duration text,
lastplayed datetime,
adjustment_level TEXT
);
CREATE TABLE IF NOT EXISTS queue (
id INTEGER primary key AUTOINCREMENT,
movie_id INTEGER
);
CREATE TABLE IF NOT EXISTS watch_log (
id INTEGER primary key AUTOINCREMENT,
movie_id INTEGER,
created DATETIME DEFAULT current_timestamp
);
CREATE TABLE IF NOT EXISTS numrand (
id INTEGER primary key autoincrement,
particle_x double,
particle_y double,
particle_direction double,
phase_0 integer,
phase_1 integer,
phase_2 integer,
phase_3 integer,
phase_4 integer,
phase_5 integer,
phase_6 integer,
phase_7 integer,
phase_8 integer,
phase_9 integer,
phase_10 integer,
phase_11 integer,
phase_12 integer 
);
CREATE TABLE IF NOT EXISTS settings (
id INTEGER primary key autoincrement,
property TEXT,
value TEXT
);
CREATE TABLE IF NOT EXISTS genres (
id INTEGER primary key autoincrement,
name TEXT,
checked BOOLEAN DEFAULT 1
);
CREATE TABLE IF NOT EXISTS locations (
id INTEGER primary key AUTOINCREMENT,
location 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);

		$this->live_indexing = new cinema_indexing($base_instance);
	}

	/*public function get_last_played_movie_folder($v=NULL) {
		if($object->isset($v['folder_id'])) && $v['folder_id'] != NULL) {

		} else {
			$query = 'SELECT * FROM watch_log ';
		}
	}*/

	public function get_songs_order($v) {
		$query = 'SELECT songs_order FROM folders WHERE id = ?';
		return $this->data->get_row($query, [$v['id']]);
	}

	public function get_currently_watching($v=NULL) {
		$query = 'SELECT * FROM status';
		$items_status = $data->player_main_instance->get_rows($query, []);

		$results = [];

		foreach($items_status as $item) {
			$query = 'SELECT * FROM movies WHERE filepath = ?';
			$movies = $this->data->get_rows($query, [$item['video_path']]);
			if($movies->length > 0) {
				$results[] = $movies[0];
			}
		}

		return $results;
	}

	private $live_indexing;

	public function init_live_indexing($v=NULL) {
		$tv_locations = $this->get_indexing_sources();

		$this->live_indexing->init($tv_locations);

		return ['result' => true];
	}

	public function get_indexing_sources() {
		$tv_locations = $object->map($this->get_sources(), function($e) {
			$location = $e['location'];
			if($object->strings->strpos($object->strings->strrev($location), '/') !== 0) {
				$location = $location.'/';
			}
			return $location;
		});
		return $tv_locations;
	}

	public function has_run() {
		$query = 'SELECT * FROM settings WHERE property = ?';
		$rows = $this->data->get_rows($query, ['has_run']);
		if($rows->length == 0) {
			$v = [
				'property' => 'has_run',
				'value' => '1'
			];

			$insert = $this->data->statement->generate($v, 'settings');
			$this->data->_($insert, $v);
			return false;
		}
		return true;
	}

	public $extensions = ['m4v', 'mp4', 'mkv', 'avi', 'wmv', 'mov', 'flv', '3gp', 'mpg', 'ts', 'rm', 'swf'];

	public function index_movies($path) {
		$files_list = $files->list_files($path);
		$total_length = $files_list->length;
		$counter = 0;
		foreach($files_list as $file) {
			$full_path = $files->append_path($path, $file);
			if($files->is_dir($full_path)) {
				$this->index_movies($full_path);
			} else if($object->strings->strlen($file) > 0 && $object->strings->strlen($full_path) > 0 && $object->index_of($this->extensions, $files->get_extension($file)) !== (-1) && $object->strpos($file, '.') != 0) {

				$query = 'SELECT * FROM movies WHERE filepath = ?';
				$rows = $this->data->get_rows($query, [$full_path]);


				$query = 'SELECT * FROM movies WHERE filename = ?';
				$rows_2 = $this->data->get_rows($query, [$file]);
				
				$episode_id = NULL;
				if($rows->length == 0 && $rows_2->length == 0) {
					$episode_id = $this->_movie([
						'path' => $full_path
					]);
					if($episode_id != NULL) {
						$this->update_movie([
							'id' => $episode_id,
							'filename' => $file
						]);
						$this->find_year_movie($episode_id, $file);
					}
				} else {
					if($rows->length > 0) {
						$episode_id = $rows[0]['id'];
					} else if($rows_2->length > 0) {
						$episode_id = $rows_2[0]['id'];
					}
					$this->update_movie([
						'id' => $episode_id,
						'filepath' => $full_path
					]);
				}
				if($episode_id != NULL) {
					$this->set_episode_index['ep_'.$episode_id] = true;
				}
			}
			$progress = $math->mult(($counter / $total_length), 100);
			$object->send('app.set_progress(data)', ['data' => $progress]);	
			$counter = $counter+1;
		}
	}

	public $set_episode_index = NULL;



	/*public function index_library($v=NULL) {
		$this->init_live_indexing(NULL);
	}*/

	public function index_library_manually($v=NULL) {
		$self = $this;
		if($this->base_instance->indexing_dictionary['cinema']) {
			return ['result' => 3];
		}
		$this->base_instance->indexing_dictionary['cinema'] = true;
		$this->base_instance->indexing_in_progress = true;
		$wrap = async function($callback) {
			$result = $self->index_library_sub();

			$callback();
			$object->send('app.cinema.settings_main.indexing_completed(data)', ['data' => $result]);
		};
		$wrap(function() {
			$self->base_instance->indexing_in_progress = false;
		});
		return ['result' => 1];
	}

	public function index_library_sub($v=NULL) {
		$files_index = [];
		$this->set_episode_index = ['test' => 1];
		delete $this->set_episode_index['test'];
		$sources = $this->get_sources();
		
		if($sources->length == 0) {
			return ['result' => 0];
		}

		foreach($sources as $source) {
			$location = $source['location'];

			if(!$files->is_readable($location)) {
				$this->base_instance->indexing_dictionary['cinema'] = false;
				return ['result' => -1];
			}
		}


		foreach($sources as $source) {
			$location = $source['location'];

			if($files->exists($location) && $files->is_dir($location)) {
				$this->index_movies($location);
			}
		}
		
		$query = 'SELECT * FROM movies';
		$episodes = $this->data->get_rows($query, []);
		if($this->set_episode_index != NULL && $object->values($this->set_episode_index)->length > 0) {
			foreach($episodes as $episode) {
				if($episode['id'] != NULL) {
					if(!$object->isset($this->set_episode_index['ep_'.$episode['id']])) {
						$query = 'DELETE FROM movies WHERE id = ?';
						$this->data->execute($query, [$episode['id']]);
					}
				}
			}
		}
		$this->base_instance->indexing_dictionary['cinema'] = false;
		return ['result' => 1];
	}

	public function _pref($v) {
		$query = 'DELETE FROM preferences';
		$this->data->execute($query, []);
		$insert = $this->data->statement->generate($v, 'preferences');
		$this->data->_($insert, $v);
		$id = $this->data->last_id($v);
		return $id;
	}

	public function _location($v) {
		$insert = $this->data->statement->generate($v, 'locations');
		$this->data->_($insert, $v);
		$id = $this->data->last_id($v);
		return $id;
	}

	public function get_sources($v=NULL) {
		$query = 'SELECT tv_shows_location, movies_location FROM preferences';
		$preferences = $this->data->get_rows($query, []);
		if($preferences->length > 0) {
			/*$locations = $object->concat([[
				'id' => 0,
				'location' => $preferences[0]['tv_shows_location']
			]], $locations);*/

			$this->_location([
				'location' => $preferences[0]['tv_shows_location']
			]);
			$query = 'DELETE FROM preferences';
			$this->data->execute($query, []);
		}

		$query = 'SELECT * FROM locations';
		$locations = $this->data->get_rows($query, []);

		return $locations;
	}

	public function set_sources($v) {
		$locations = $v['locations'];
		$location_ids = [];
		foreach($locations as $key => $location) {
			if($object->isset($location['id']) && $location['id'] == 0) {
				$this->_pref([
					'tv_shows_location' => $location['location']
				]);
			} else {
				$location_ids[] = $this->_location($location);
			}
		}
		foreach($locations as $location) {
			if($object->isset($location['id']) && $object->index_of($location_ids, $location['id']) === (-1)) {
				$location_ids[] = $location['id'];
			}
		}
		$sources = $this->get_sources();
		foreach($sources as $source) {
			if($object->index_of($location_ids, $source['id']) === (-1)) {
				$query = 'DELETE FROM locations WHERE id = ?';
				$this->data->execute($query, [$source['id']]);
			}
		}
		/*$this->init_live_indexing();*/
		return ['result' => 1];
	}

	public function _movie($v) {
		$path = $v['path'];
		if($object->strings->strlen($path) > 0) {
			$query = 'SELECT id FROM movies WHERE filepath = ?';
			$rows = $this->data->get_rows($query, [$path]);
			$id = NULL;
			if($rows->length > 0) {
				$id = $rows[0]['id'];
			}
			$v = [
				'filepath' => $path
			];
			if($id != NULL) {
				$v['id'] = $id;
			}

			$insert = $this->data->statement->generate($v, 'movies');
			$this->data->_($insert, $v);
			$id = $this->data->last_id($v);
			return $id;
		}
		return NULL;
	}

	public function find_year_movie($id, $filepath=NULL) {
		if($filepath == NULL) {
			return NULL;
		}
		$match = $object->regex->reg_match('[0-9]{4}(?!p)', $filepath);
		$found = false;
		foreach($match as $match) {
			if(!$found) {
				$found = true;
				$year = $match['value'];
				$v = [
					'id' => $id,
					'year' => $year
				];
				$insert = $this->data->statement->generate($v, 'movies');
				$this->data->_($insert, $v);
			}
		}
		return NULL;
	}

	public function update_movie($v) {
		$query = 'SELECT deleted FROM movies WHERE id = ?';
		$row_deleted = $this->data->get_row($query, [$v['id']]);
		if($row_deleted != NULL) {
			if($row_deleted['deleted'] == 1) {
				$v['deleted'] = 0;
			}
		}
		$insert = $this->data->statement->generate($v, 'movies');
		$this->data->_($insert, $v);
		$id = $this->data->last_id($v);
		return $id;
	}
	
	public function add_movie_to_folder($v) {
		$this->remove_movie_from_folder($v);
		$insert = $this->data->statement->generate($v, 'movie_folder');
		$this->data->_($insert, $v);
		$id = $this->data->last_id($v);
		return $id;
	}

	public function remove_movie_from_folder($v) {
		$query = 'DEL FROM movie_folder WHERE movie_id = ? AND folder_id = ?';
		$this->data->execute($query, [$v['movie_id'], $v['folder_id']]);
		return ['result' => 1];
	}

	public function remove_from_queue($v) {
		$query = 'DEL FROM queue WHERE movie_id = ?';
		$this->data->execute($query, [$v['movie_id']]);
		return ['result' => 1];
	}

	public function add_to_queue($v) {
		$query = 'DEL FROM queue WHERE movie_id = ?';
		$this->data->execute($query, [$v['movie_id']]);
		$insert = $this->data->statement->generate($v, 'queue');
		$this->data->_($insert, $v);
		$id = $this->data->last_id($v);
		return $id;
	}

	public function reset($v) {
		$this->data->execute('DELETE FROM folders', []);
		$this->data->execute('DELETE FROM movie_folder', []);
		$this->data->execute('DELETE FROM movies', []);
		$this->data->execute('DELETE FROM queue', []);
		$this->data->execute('DELETE FROM watch_log', []);
		return ['result' => 1];
	}

	public function delete_history($v=NULL) {
		$query = 'DELETE FROM watch_log';
		$this->data->execute($query, []);
		return true;
	}

	public function toggle_movie($v) {
		$insert = $this->data->statement->generate($v, 'movies');
		$this->data->_($insert, $v);
		$id = $this->data->last_id($v);
		return $id;
	}

	

	public function preferences($v) {
		$insert = $this->data->statement->generate($v, 'preferences');
		$this->data->_($insert, $v);
		$id = $this->data->last_id($v);
		return $id;
	}

	public function play_movie($v) {
		$query = 'SELECT * FROM movies WHERE id = ?';
		$row = $this->data->get_row($query, [$v['id']]);
		if($row->length > 0 && $object->isset($row['filepath'])) {
			$path = $row['filepath'];

			$this->base_instance->apps['player']->play(['path' => $path]);

			$v = [
				'movie_id' => $v['id']
			];
			$insert = $this->data->statement->generate($v, 'watch_log');
			$this->data->_($insert, $v);
			return $path;
		}
		return NULL;
	}


	public function reset_years($v) {
		$query = 'SELECT * FROM movies WHERE year IS NULL OR Length(year) = 0';
		$rows = $this->data->get_rows($query, []);
		foreach($rows as $row) {
			$this->find_year_movie($row['id'], $row['filename']);
		}
		return ['result' => 1];
	}

	public function save_setting($v) {
		$query = 'DEL FROM settings WHERE property = ?';
		$this->data->execute($query, [$v['property']]);
		$insert = $this->data->statement->generate($v, 'settings');
		$this->data->_($insert, $v);
		$id = $this->data->last_id($v);
		return $id;
	}

	public function update_genre($v) {
		$insert = $this->data->statement->generate($v, 'genres');
		$this->data->_($insert, $v);
		return ['result' => 1];
	}

	public function del_genre($v) {
		$query = 'DEL FROM genres WHERE id = ?';
		$this->data->execute($query, [$v['id']]);
		$query = 'UPDATE movies SET genre = NULL WHERE genre = ?';
		$this->data->execute($query, [$v['id']]);
		return ['result' => 1];
	}

	public function set_playlist_order($v) {
		$query = 'SELECT COUNT(*) as count FROM folders WHERE id = ?';
		$count = $this->data->get_row($query, [$v['id']])['count'];
		$set_type = (-1);
		if($count == 0) {
			$set_type = 1;
		}
		$insert = $this->data->statement->generate($v, 'folders', $set_type);
		$this->data->_($insert, $v);
		return ['result' => 1];
	}

	public function queue($v) {
		$query = 'SELECT movies.* FROM movies, queue WHERE movies.id = queue.movie_id ORDER BY queue.id ASC';
		return $this->data->get_rows($query, []);
	}

	public function get_genres($v) {
		$query = 'SELECT * FROM genres';
		return $this->data->get_rows($query, []);
	}

	public function get_settings($v) {
		$query = 'SELECT * FROM settings';
		return $this->data->get_rows($query, []);
	}

	public function get_setting($v) {
		$query = 'SELECT * FROM settings WHERE property = ?';
		return $this->data->get_row($query, [$v['property']]);
	}

	public function clear_queue($v) {
		$query = 'DEL FROM queue';
		$this->data->execute($query, []);
		return ['result' => 1];
	}

	public function del_movie($v) {
		$id = $v['id'];
		$query = 'DEL FROM movies WHERE id = ?';
		$this->data->execute($query, [$id]);
		return ['result' => 1];
	}

	public function favorite_movie($v) {
		$insert = $this->data->statement->generate($v, 'movies');
		$this->data->_($insert, $v);
		$id = $this->data->last_id($v);
		return $id;
	}

	public function del_folder($v) {
		$query = 'DEL FROM folders WHERE id = ?';
		$this->data->execute($query, [$v['id']]);
	}

	public function folder($v) {
		$insert = $this->data->statement->generate($v, 'folders');
		$this->data->_($insert, $v);
		$id = $this->data->last_id($v);
		return $id;
	}

	public function get_favorites($v) {
		$query = 'SELECT * FROM movies WHERE favorite = 1  ORDER BY movies.filename ASC';
		return $this->data->get_rows($query, []);
	}

	public function get_folder($v) {
		$id = $v['id'];
		$query = 'SELECT * FROM folders WHERE id = ?';
		return $this->data->get_rows($query, [$id]);
	}

	public function get_movie($v) {
		$query = 'SELECT * FROM movies WHERE id = ?';
		return $this->data->get_row($query, [$v['id']]);
	}

	public function get_movies($v) {
		$query = 'SELECT * FROM movies WHERE deleted = 0 ORDER BY filename ASC';
		return $this->data->get_rows($query, []);
	}

	public function get_movie_by_path($path) {
		$query = 'SELECT * FROM movies WHERE filepath = ?';
		return $this->data->get_row($query, [$path]);
	}

	public function toggle_movie_by_path($path) {
		$movie = $this->get_movie_by_path($path);
		if($movie != NULL) {
			$checked_value = 1;
			if($movie['checked'] == 1) {
				$checked_value = 0;
			}
			$v = [
				'id' => $movie['id'],
				'checked' => $checked_value 
			];
			$this->update_movie($v);
		}
	}

	public function get_folders($v) {
		$query = 'SELECT * FROM folders WHERE id > 0';
		$rows = $this->data->get_rows($query, []);
		return $rows;
	}

	public function get_folder_movies($v) {
		$query = 'SELECT movies.* FROM movie_folder, movies WHERE movie_folder.movie_id = movies.id AND movie_folder.folder_id = '.$v['folder_id'].' ORDER BY movies.filename ASC';
		return $this->data->get_rows($query, $v);
	}

	public function get_trash($v) {
		$query = 'SELECT * FROM movies WHERE deleted = 1 ORDER BY filepath ASC';
		return $this->data->get_rows($query, []);
	}

	public function get_preferences($v) {
		$query = 'SELECT tv_shows_location, movies_location FROM preferences';
		$rows = $this->data->get_rows($query, []);
		if($rows->length == 0) {
			return [];
		}
		return $rows[0];
	}

	public function get_recently_added($v) {
		$recently_viewed_date_interval = $this->get_setting(['property' => 'recently_viewed_date_interval']);
		$year_interval = (-1);
		if($recently_viewed_date_interval != NULL) {
			if($object->isset($recently_viewed_date_interval['value'])) {
				$year_interval = (-$recently_viewed_date_interval['value']);
			}
		}
		$date = $date->get_date('default', $year_interval, 0, 0);
		$query = 'SELECT * FROM movies WHERE deleted = 0 AND created > ? ORDER BY movies.filepath ASC';
		return $this->data->get_rows($query, [$date]);
	}

	public function get_recently_not_watched($v) {
		$recently_viewed_date_interval = $this->get_setting(['property' => 'recently_viewed_date_interval']);
		$year_interval = (-1);
		if($recently_viewed_date_interval != NULL) {
			if($object->isset($recently_viewed_date_interval['value'])) {
				$year_interval = (-$recently_viewed_date_interval['value']);
			}
		}
		$date = $date->get_date('default', $year_interval, 0, 0);
		$query = 'SELECT DISTINCT * FROM movies WHERE deleted = 0 AND (SELECT COUNT(*) FROM watch_log WHERE watch_log.movie_id = movies.id) = 0 UNION SELECT movies.* FROM movies, watch_log WHERE deleted = 0 AND movies.id = watch_log.movie_id AND watch_log.created < ? ORDER BY movies.filepath ASC';
		return $this->data->get_rows($query, [$date]);
	}

	public function get_recently_watched($v) {
		$recently_viewed_date_interval = $this->get_setting(['property' => 'recently_viewed_date_interval']);
		$year_interval = (-1);
		if($recently_viewed_date_interval != NULL) {
			if($object->isset($recently_viewed_date_interval['value'])) {
				$year_interval = (-$recently_viewed_date_interval['value']);
			}
		}
		$date = $date->get_date('default', $year_interval, 0, 0);
		$query = 'SELECT DISTINCT movies.* FROM movies, watch_log WHERE deleted = 0 AND movies.id = watch_log.movie_id AND watch_log.created > ? ORDER BY watch_log.created DESC';
		return $this->data->get_rows($query, [$date]);
	}

	public function _numrand($v) {
		$query = 'DEL FROM numrand';
		$this->data->execute($query, []);
		$insert = $this->data->statement->generate($v, 'numrand');
		$this->data->_($insert, $v);
		$id = $this->data->last_id($v);
		return ['id' => $id];
	}

	public function get_state($v) {
		$query = 'SELECT * FROM numrand ORDER BY id DESC LIMIT 1';
		$rows = $this->data->get_rows($query, []);
		if($rows->length == 0) {
			return [];
		}
		return $rows[0];
	}

	public function play_random_movie($v=NULL) {
		$object->log('folder id');
		$object->log($v['folder_id']);
		if($v['folder_id'] == (-1)) {
			return $this->get_recently_not_watched(NULL);
		}
		$date = $date->get_date('default', 0, -6, 0);
		$query = 'SELECT movies.* FROM movies, movie_folder WHERE movie_folder.movie_id = movies.id AND movie_folder.folder_id = '.$v['folder_id'].' AND movies.deleted = 0 AND (SELECT COUNT(*) FROM watch_log WHERE watch_log.movie_id = movies.id) = 0 UNION SELECT movies.* FROM movies, watch_log, movie_folder WHERE movie_folder.movie_id = movies.id AND movie_folder.folder_id = '.$v['folder_id'].' AND deleted = 0 AND movies.id = watch_log.movie_id AND watch_log.created < ? ORDER BY movies.filepath ASC';
		$object->log($query);
		$rows = $this->data->get_rows($query, [$date]);
		return $rows;
	}
}

?>