<?

/*

Автоподбор параметров:
1. выбираем максимально хорошую скорость в зависимости от процента места которым жертвуем
2. проводим анализ:
	если все ок, выходим
	если места слишком мало получилось, смещаем ползунок на средину, запускаем сканирование
		если лишнее место, делим к
3. если превысили, 

*/

/*

$cur_speed_index
work = 1,0

1. берем вариант, запускаем
2. смотрим, если итоговое место слишком мало, берем следуещее, иначе тормозимся


*/



class Analize_autochoice {

	// пока тупой алгоритм. Просто перебираем скорости из прописанных в этом массиве. От больше к меньшей.

	// максимальное число 10 не просто так. Потому что большие значения могут повлиять на фрагментируемость из-за погрешности определения скорости.
	private $speed_mas = array(15, 12, 10, 8, 7, 6, 5, 4, 3, 2, 1.5); // array(22, 15, 12, 10, 7, 5, 4, 3, 2, 1.5); // именно в обратном порядке. 22 это реальный порог на графике.
	private $cur_speed_key = -1; // при старте подбора должно быть это значение
	private $status = 'start';
	private $min_result_space = 0;

	private $stopped = false; // человек захотел остановить процесс подбора

	private $bt_run = 'bt_autochoice_run';
	private $bt_stop = 'bt_autochoice_stop';
	private $lb_msg = 'lb_autochoice_msg';	
	private $bg_msg = 'bg_autochoice_msg';

	protected $fmName = 'Fm';

	function __construct() {
	}

	function get_podbor_max_speed() {
		return $this->speed_mas[0];
	}

	function get_status() {
		return $this->status;
	}

	// позволяет запустить подбор по новой
	function start() {
		GLOBAL $Ui_thread, $Graphs, $log, $Disc_info, $INFO, $OP, $Bt_run, $Ui_fields;

		if($INFO['step'] != 'analize_blocks')
			return ;

		if($Ui_thread->check_run_dialog())
			return ;

		// вкл/выкл кнопок start, stop
		c($this->fmName .'->'.$this->bt_run)->enabled = false;
		c($this->fmName .'->'.$this->bt_stop)->enabled = true;

		Ui_over::all_bt_run_enabled(false);

		// делаем белый фон
		c($this->fmName .'->'.$this->bg_msg)->brushColor = str_to_color('ffffff');

		$this->msg("Идет автоподбор, ждите...");

		//$log->line("autochoice start");
		$this->cur_speed_key = -1;
		$this->status = 'process';

		$blocked_proc = $Ui_fields['autochoice_blocked_size_proc']->get();
		$blocked_proc = trim(str_replace('%', '', $blocked_proc));
		$result_size_proc = (100 - $blocked_proc) / 100; // будет например 0.8
		//$log->line("Будет доступно $result_size_proc % места");

		// в $Disc_info->testing_size не учитываются пользовательские файлы. Поэтому вычитаем их здесь. Но надо учитывать, чтобы не стояла галочка use_part
		$available_space = $Disc_info->testing_size;
		//if(!$OP['use_part']) {
		//	$available_space -= $INFO['stat_userfiles'];
		//}

		$this->min_result_space = $available_space * $result_size_proc / 1024;
		$this->next_speed();

		$Bt_run->onClick('analize_blocks');

		return true;
	}

	// включаем, выключаем кнопки
	function bt_enable($type, $enable) {
		
	}

	// style = размер и жирность шрифта. big - для показа статусов. small - для результатов где много текста
	function msg($text, $style = 'big') {
		$label = c($this->fmName .'->'.$this->lb_msg);
		$label->text = $text;

		if($style == 'big') {
			$size = 12;
			$style = 'fsBold';
			$color = 0x0000ff;
		}
		else {
			$size = 9;
			$style = '';
			$color = 0x000000;
		}

		$label->font->style = $style;
		$label->font->size = $size;
		$label->font->color = $color;
	}

	function stop() {
		GLOBAL $Ui_thread;

		if($this->status != 'process') return;

		$this->stopped = true;

		if($Ui_thread->check_run())
			 $this->msg("останавливаю... (дождитесь конца пересчета)");
		else 
			$this->finish();
	}

	// срабатывает когда пересчет выполнен
	function finish() {
		GLOBAL $OP, $Ui_fields, $Measure_convert;

		$this->status = 'finish';
		
		// вкл/выкл кнопок start, stop
		c($this->fmName .'->'.$this->bt_run)->enabled = true;
		c($this->fmName .'->'.$this->bt_stop)->enabled = false;

		Ui_over::all_bt_run_enabled(true);

		if($this->stopped)
			 $text = "автоподбор прерван";
		else {

			$min_speed = $Ui_fields['analize_good_speed']->get();
			$result_space = Stat::realtime_result_space();
			$result_space = $Measure_convert->pretty_size($result_space, "MB", false);

			c($this->fmName .'->'.$this->bg_msg)->brushColor = str_to_color('ddddff');

			$text = "
Мин. скорость чтения: $min_speed MB/s
Вы получите: $result_space  (остальное заблок.)
Если устраивает, нажмите \"Завершающий этап\"";

			$text = trim($text);

			if(!$OP['step_analize_autoprohod']) {
				print "Автоподбор завершен\n\n" . $text;
			}
			
			// подсвечиваем кнопку
			visible_group('next_analize_blocks', true);
		}

		$this->msg($text, 'small');

		$this->stopped = false;
	}

	function iter() {
		GLOBAL $Graphs, $log, $Disc_info, $INFO, $OP, $Bt_run;
		
		$bar = $Graphs['speed']->select_bar;

		if($this->stopped) {
			$this->finish();
			return true;
		}
		
		if($this->status == 'process') {
			//$log->line("autochoice process");
			// анализ результатов сканирования
			$result_space = Stat::realtime_result_space();

			// если не подошло, берем следующую скорость
			if($result_space < $this->min_result_space) {
				//$log->line("result_space > мин. результата: $result_space > {$this->min_result_space} ");
				// если еще скорость есть, запускаем
				if($this->next_speed()) {
					//$log->line("еще есть скорость, запускаем");
					$Bt_run->onClick('analize_blocks');
					return true;
				}
			}

			$this->finish();
			return true;
		}
	}


	function next_speed() {
		GLOBAL $Graphs, $log, $OP;

		$bar = $Graphs['speed']->select_bar;

		$this->cur_speed_key ++;
	
		//$log->line("next_speed(): предварительный новый ключ " . $this->cur_speed_key);

		// если скорости закончились
		if(!isset($this->speed_mas[$this->cur_speed_key])) {
			//$log->line("next_speed(): Скорости закончились");
			return false;
		}

		$speed_mb = $this->speed_mas[$this->cur_speed_key];

		// если скорость меньше базовой, выходим
		if($speed_mb < $OP['good_speed']) {
			//$log->line("next_speed(): Скорость меньше базовой, завершаем");
			return false;
		}

		if($this->cur_speed_key == 0) {
			// проверяем, может эта скорость нам не подходит
			$speed_by_graph = $this->check_by_graph_speed($speed_mb, $this->min_result_space);

			//$log->line("скорость по графику: $speed_by_graph");

			// пропускаем элементы 
			$tmas = $this->speed_mas;
			sort($tmas);
			$mas = array_fill_keys($tmas, 0);
			list($speed_mb) = near_keys($mas, $speed_by_graph);

			$this->cur_speed_key = array_search($speed_mb, $this->speed_mas);
		}

		//$log->line("устанавливаем скорость: $speed_mb");

		$bar->set_mb($speed_mb);

		return true;
	}

	function check_by_graph_speed($max_speed, $min_size) {
		GLOBAL $Graphs, $log, $Disc_info, $INFO, $OP;

		$bar = $Graphs['speed']->select_bar;
		$rate = 0.15; // сколько можно занять пространства, проценты. От 0 до 1
		//$max_speed = 2000;
		$bar->set_mb($OP['good_speed']);

		//устанавливаем ползунок на минимальное значение
		//$min_size = $Disc_info->testing_size * 0.85 / 1024;
		//$log->line("check_by_graph_speed(): мин. размер итог место=$min_size; max_speed=$max_speed");

		while(true) {
			$result_space = Stat::realtime_result_space();
			//$log->line("$result_space > $min_size");

			// все правильно, достаточно только этих условий
			// потому что $result_space сначала максимальный а потом уменьшается.
			if($result_space > $min_size and $bar->get_mb() < $max_speed) {
				$res = $bar->next_point();
				 // вышли за рамки графика, либо неправильно выбран interval_point в select_bar
				if(!$res)
					break;
			}
			else break;
		}

		return $bar->get_mb();
	}
}

?>