<?

class main_app {

	private $sql;
	
	private $statement;

	private $dates;

	public $base_instance = NULL;

	public $items;

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

		/*$this->items = [
			'deleted_videos' => new deleted_videos('deleted_videos', $this->sql, $this->statement)
		];*/

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

		$init_string = 'CREATE TABLE IF NOT EXISTS settings (
			id INTEGER primary key autoincrement,
			property_name TEXT,
			property_value TEXT );

			CREATE TABLE IF NOT EXISTS deleted_videos (
				id text primary key,
				youtube_id text
			);
		';

		$init_tables = $object->strings->split($init_string, ';');

		foreach($init_tables as $init_table) {
			if($init_table != NULL && $object->strings->strlen($init_table) > 0) {
				$this->sql->execute($init_table, []);
			}
		}
		$table_update = new table_structure_update($init_string, $this->sql);


		/*$this->media = $media->add_tab(NULL);

		$this->media->register_callback(function($par) {
			return 0;
		});
		$this->media->register_callback(function($par) {
			return 0;
		});
		$this->media->register_callback(function($par) {
			$object->send('app.ended(data)', ['data' => NULL]);
		});

		$this->collections = new collections('collections', $this->sql, $this->statement);
		$this->additional_locations = new additional_locations('locations', $this->sql, $this->statement);

		$object->log('run main');*/

		$this->run_main();

		/*$object->debug_time(true);

		$permutations = new permutations([1, 2, 3, 4, 5, 6, 7]);
		$res = $permutations->generate();

		$object->log($object->toJSON($res));

		$time = $object->debug_time(false);

		$object->log('debug time');
		$object->log($time);*/
	}

	

	public $set_conf_values = NULL;



	public function set_conf($v) {
		/*$this->fractions_length = $object->splice($v['conf'], 0, 1][0];*/

		$object->log($object->toJSON(['set conf call' => $v]));

		$this->set_conf_values = [...$v['conf']];
		/*$object->set_conf_values = $this->set_conf_values;*/
	}


	private $web_main_item;

	public function run_main() {

		$evaluation_test = new evaluation();
		$test_value = $evaluation_test->remove_leading_zeros('00001232401');
		$object->log('test value');
		$object->log($test_value);
		/*$preg_split = new preg_split('(<|>|\")', '<value prop="test"></value>');
		$res = $preg_split->get();
		$object->log($object->toJSON($res));*/
		$self = $this;

		/*$this->set_conf = $object->create();*/

		$this->tabs = $object->create();

		$source = $files->read_text('streamline2/main', 'html');
		/*
				<div class="c_container">
					<video class="preview"></video>
				</div>*/
		/*
				<div class="web_container">
					<web></web>
				</div>*/


		$html_parser_instance = new html_parser($source);
		$res = $html_parser_instance->parse();

		$object->log('run main1');
		$object->log($res);

		$web_main_item = $res->get_window()->get_document()->query_selector('.mainweb')[0];

		$web_main_item->get_webview()->init_messages(function($message_value) {
			$object->log($object->toJSON($message_value));
			if($object->isset($message_value['action'])) {
				if($message_value['action'] == 'start_server') {
					
					$object->start_ws_server($message_value['ip'], $message_value['port'], function($res) {
						$object->log($res);
					});

					$data_res = [
						'message' => true,
						'message_counter' => $message_value['message_counter']
					];
		    		$web_main_item->get_webview()->evaluate('app.receive_messages(data)', function($res_data) {
		    			$object->log('test1');
		    		}, ['data' => $data_res]);

					return false;
				}
				/*$data_res = $self->base_instance->receive_messages($message_value);*/

				if($message_value['action'] == 'set_conf') {
					$self->set_conf($message_value);


					$value_result = ['result' => true];

					$data_res = [
						'message' => $value_result,
						'message_counter' => $message_value['message_counter']
					];


		    		$web_main_item->get_webview()->evaluate('app.receive_messages(data)', function($res_data) {
		    			$object->log('test1');
		    		}, ['data' => $data_res]);

		    		return false;
				}

				$values = $message_value['values'];

				$evaluation = new evaluation();

				if($self->set_conf_values != NULL) {
					$evaluation->set_conf($self->set_conf_values);
				}

				/*$call_callback = function() {
				};

				if($self->set_conf != NULL) {
					$object->call_func($evaluation->__set_configuration, $self->set_conf, function($res) {
						$call_callback();
					});
				} else {
					$call_callback();
				}*/

				$object->log('evaluation');

				$object->log($evaluation);

				$action = $evaluation[$message_value['action']];


				$object->log($action);

				$result_callback = function($value_result) {
					if($message_value['action'] == 'root' && $value_result == (-1)) {
						$value_result = $evaluation->root_closest_result;
					}
					/*$object->log($object->toJSON($value_result));*/
					if($object->item_is_array($value_result) && !$object->item_is_array($value_result, true) && $object->isset($value_result['remainder'])) {
						$value_result['remainder'] = $evaluation->execute_shorten_fraction($value_result['remainder'], true);
					}
					$data_res = [
						'message' => $value_result,
						'message_counter' => $message_value['message_counter']
					];
					$object->log($object->toJSON(['datares', $data_res]));
					if($object->isset($data_res) && $data_res != NULL && $data_res['message_counter'] != (-1)) {
						$object->log('evaluate');
			    		$web_main_item->get_webview()->evaluate('app.receive_messages(data)', function($res_data) {
			    			$object->log('test1');
			    		}, ['data' => $data_res]);
			    	}
			    };

				if($message_value['action'] == 'trigonometry_radian') {
					$object->log('trigonometry_radian');
					$over = false;
					if($values->length > 1) {
						$over = $values[1];
					}
					$evaluation->trigonometry_radian($values[0], $over, $result_callback);
				} else {

					$object->call_func($action, $values, $result_callback);
				}
				
			}
		});

		
		$object->log('run main completed');
	}

	public function make_accessible($path, $callback=NULL) {
		$self = $this;
		if(!$files->is_readable($path)) {
			$picker_callback = function($url) {
				/*$object->log('picker result');
				$object->log($url);
				$object->log($path);*/
				if(!$files->is_readable($path)) {
					$self->access_timeout_counter++;
					$self->make_accessible($callback);
				} else {
					if($callback != NULL) {
						$callback();
					}
				}
			};
			$files->picker($path, true, false, $picker_callback);
		} else {
			if($callback != NULL) {
				$callback();
			}
		}
		return ['result' => 1];
	}

	public $access_timeout_counter = 0;

	public function make_accessible_multiple($paths, $callback=NULL) {
		if($this->access_timeout_counter > 4) {
			$object->send('app.settings.library.index_completed(data)', ['data' => 0]);
			return false;
		}
		$self = $this;

		$path = $object->array_pop($paths);

		$this->make_accessible($path, function() {
			if($paths->length > 0) {
				$this->make_accessible_multiple($paths, $callback);
			} else {
				if($callback != NULL) {
					$callback();
				}
			}
		});
		return ['result' => 1];
	}

	public function index_files($v=NULL) {
		$this->access_timeout_counter = 0;
		$this->base_instance->indexing_in_progress = true;
		$library_location = $this->get_settings_values(['property_name' => 'library_location_input']);
		/*if($library_location == NULL) {
			return ['result' => 0];
		}*/
		$additional_locations = $this->additional_locations->load();
		$self = $this;

		$sql = $this->sql;
		$statement = $this->statement;
		$wrap = async function() {
			$indexing = new indexing($sql, $statement);
			$result = $indexing->index_files($library_location);

			foreach($additional_locations as $additional_location) {
				$library_location = $additional_location['path'];
				$result = $indexing->index_files($library_location, $additional_location['id']);
			}


			$self->base_instance->indexing_in_progress = false;

			$object->send('app.settings.library.index_completed(data)', ['data' => $result]);
		};

		$additional_locations_and_library = $object->map($additional_locations, function($e) {
			return $e['path'];
		});
		if($library_location != NULL) {
			$additional_locations_and_library[] = $library_location;
		}
		
		$this->make_accessible_multiple($additional_locations_and_library, $wrap);
		return ['result' => 0];
	}

	public function login_grant_access($v=NULL) {
		$library_location = $this->get_settings_values(['property_name' => 'library_location_input']);

		$additional_locations = $this->additional_locations->load();


		$additional_locations_and_library = $object->map($additional_locations, function($e) {
			return $e['path'];
		});
		$additional_locations_and_library[] = $library_location;

		$this->make_accessible_multiple($additional_locations_and_library, NULL);

		return true;
	}
	
	public function clean_files($v=NULL) {
		$this->access_timeout_counter = 0;
		$this->base_instance->indexing_in_progress = true;
		$library_location = $this->get_settings_values(['property_name' => 'library_location_input']);
		if($library_location == NULL) {
			return ['result' => 0];
		}
		$additional_locations = $this->additional_locations->load();

		$self = $this;

		$sql = $this->sql;
		$statement = $this->statement;

		$wrap = async function() {
			$indexing = new indexing($sql, $statement);
			$result = $indexing->clean_files($library_location);

			$indexing->clean_lost_locations($additional_locations);

			foreach($additional_locations as $additional_location) {
				$library_location = $additional_location['path'];
				$result = $indexing->clean_files($library_location, $additional_location['id']);
			}


			$object->send('app.settings.library.index_completed(data)', ['data' => $result]);
			$self->base_instance->indexing_in_progress = false;
		};
		$wrap();
		return ['result' => 0];
	}

	

	public function get_playlists_for_song($v) {
		$query = 'SELECT playlist_id FROM playlist_songs WHERE song_id = ?';
		return $this->sql->get_rows($query, [$v['song_id']]);
	}

	public function save_smart_folder($v) {
		$item = $v['item'];
		$insert_data = [
			'name' => $item['name']
		];
		$filter_id = NULL;
		if($object->isset($item['id'])) {
			$insert_data['id'] = $item['id'];
			$filter_id = $item['id'];
		}
		$insert = $this->statement->generate($insert_data, 'filters');
		$this->sql->_($insert, $insert_data);
		if($filter_id == NULL) {
			$filter_id = $this->sql->last_insert_id();
		}
		$query = 'DELETE FROM filter_constraints WHERE filter_id = ?';
		$this->sql->execute($query, [$filter_id]);

		foreach($v['constraints'] as $constraint) {
			$insert = $this->statement->generate($constraint, 'filter_constraints');
			$this->sql->_($insert, $constraint);
		}
		return ['result' => 1];
	}

	public function get_filters($v=NULL) {
		$query = 'SELECT * FROM filters ORDER BY id ASC';
		$rows = $this->sql->get_rows($query, []);
		return $rows;
	}

	public function save_searches($v=NULL) {
		$query = 'DELETE FROM filters';
		$this->sql->execute($query, []);
		foreach($v['saved_searches'] as $saved_search) {
			$insert_data = [
				'name' => $saved_search
			];
			$insert = $this->statement->generate($insert_data, 'filters');
			$this->sql->_($insert, $insert_data);
		}
		return ['result' => 1];
	}

	public function delete_songs($v) {
		foreach($v['playlist_songs'] as $id) {
			$query = 'DELETE FROM library WHERE id = ?';
			$this->sql->execute($query, [$id]);
			$query = 'DELETE FROM playlist_songs WHERE playlist_songs.song_id = ?';
			$this->sql->execute($query, [$id]);
		}
		return ['result' => 1];
	}

	public function save_shuffle_template($v) {
		$insert_data = [
			'tags' => $object->toJSON($v['tags'])
		];
		if($v['id'] != NULL) {
			$insert_data['id'] = $v['id'];
		}

		$insert = $this->statement->generate($insert_data, 'shuffle_templates');
		$this->sql->_($insert, $insert_data);
		$id = $this->sql->last_id($insert_data);
		return ['id' => $id];
	}

	public function get_saved_shuffle_templates($v) {
		$query = 'SELECT * FROM shuffle_templates ORDER BY id DESC';
		return $this->sql->get_rows($query, []);
	}

}

?>
