<?

/* ползунок для выделения части графика */

/* TODO: надо передалать pos в тупо пиксели. Иначе меткости не добиться*/

class Gr_select_bar {

	// больше не нужен. private $stepKb = 1; //шаг в килобайтах. Нужно править каждый раз когда меняем block_size

	private $pos_max = 500; // максимальное число шагов в трекер баре. Отсчет начинается с 0
	private $pos = 0;
	private $mb = 0;
	private $label_w = 20;
	private $point_interval = 4; // интервал достаточный для перескока на следующую отметку в сроллбаре когда мы прибавляем его к текущей позиции скроллбара

	// ссылки на объекты
	private $trackbar;
	private $line_ui;
	private $graph; // на график

	// неиспользуемое пространтво вокруг ползунка
	private $ui_margin = array('left'=>11, 'right'=>11, 'top'=>5, 'bottom'=>5);

	protected $fmName = 'Fm';

	function __construct($name, $graph, $stepKb=1) {
		$this->name = $name;
		$this->graph = $graph;
		$this->trackbar = get_ui($this->fmName.'->'.$name);
		$this->stepKb = $stepKb;
		
		// подсказка по текущему положению 
		//$this->infotip = new Graph_select_bar_tip("{$name}_tip");

		$this->info1 = new Label_no_blink($graph->name . '_info1', '', 'fsBold');
		$this->info2 = new Label_no_blink($graph->name . '_info2', '', 'fsBold');
		$this->info2->cv->font->color = 0x000000; // 0x0101CD;
		
		$this->line_ui = get_ui($this->fmName.'->'.$name . "_line");

		// изменение размеров и координат
		$this->adapt_by_graph();

		//print ($this->trackbar->w) . ", ";
		// без корректора, фактор получается немного не правильный, и это заметно на красной линии тянущейся за ползунком
		$correct = 2;
		$this->factor_pos_x = ($this->pos_max +$correct)/ ($this->trackbar->w - $this->ui_margin['left'] -  $this->ui_margin['right'] /*- 10*/);
	}


	// изменение размеров и координат трекбара под график
	function adapt_by_graph() {
		GLOBAL $log;

		$gp = $this->graph;
		$graph_ui = c($this->fmName .'->'.$gp->name);

		$abs_x0 = $graph_ui->x + $gp->xZero;

		$this->trackbar->x = $abs_x0 - $this->ui_margin['left'];
		$this->line_ui->x = $abs_x0 - 3;

		$this->trackbar->w = $gp->area_data['w'] + $this->ui_margin['left'] + $this->ui_margin['right'];
	}


	// обновления текущего положения ползунка чтобы он пересчитался
	function refresh_pos($is_redraw=true) {
		$this->set_pos('refresh', '', $is_redraw);
	}


	// переходит на следующую точку (отметку куда примагничевается ползунок)
	function next_point() {
		$cur_pos = $this->get_pos();
		$real_pos = $this->set_pos($cur_pos + $this->point_interval);
		if($real_pos == $cur_pos) {
			// если смещение не удалось (очков не хватило, либо конец графика)
			return false;
		}
		else return true;
	}
	function prev_point() {
		$cur_pos = $this->get_pos();
		$real_pos = $this->set_pos($cur_pos - $this->point_interval);

		if($real_pos == $cur_pos) {
			// если смещение не удалось (очков не хватило, либо конец графика)
			return false;
		}
		else return true;
	}

	function set_stepKb($kb) {
		$this->stepKb = $kb;
	}

	function get_mb() {
		return $this->mb;
	}
	function get_pos() {
		return $this->pos;
	}

	function set_mb($mb) {
		GLOBAL $log;

		//$log->line(__method__ . "($mb)");

		$x = $this->graph->xAxis_value_to_x($mb);
		$pos = $x * $this->factor_pos_x;

		//$log->line("set_mb() mb:$mb; x:$x; pos:$pos");
#		$pos = $this->mb_to_pos($mb);
		$this->set_pos($pos, $mb);
	}

	// $mb нужно передавать если он известен, если нет, то не нужно. По факту он нужен чтобы лишний раз pos_to_mb не запускать.
	//$pos = 'refresh' позволяет пересчитать текущую позицию. Потому что если укажем pos который установлен, то метод не выполнится
	function set_pos($pos /*число или refresh*/, $mb='',  $is_redraw=true) {
		GLOBAL $log, $Measure_convert;
	

		// проверку что нажал человек можно определить через проверку в этом месте координаты мышки. Они должны совпасть с ползунком.

		$is_refresh = false;
		
		if($pos == 'refresh') {
			$is_refresh = true;
			$pos = $this->get_pos();
		}
		else {
			$pos = round_nobug($pos);

			// опять же чтобы она сам себя не трахал
			if($pos == $this->pos) {
				//$log->line( __method__ . "($pos, $mb) блокировка");
				return true;
			}
		}
		
		//$log->line(time() . ' set_pos() ' . $s . ' '. $pos . ' ' . $mb . ' ' . $is_redraw);

		// переходить только по сегментам
		// ищем ближайший столбец и используем его
		$x = $pos / $this->factor_pos_x;

		if(!$mb and $pos) {
			$mb = $this->graph->xAxis_x_to_value($x); // $this->pos_to_mb($pos);
		}
		if(!$pos) $mb = 0;

		list($floor, $ceil, $near) = $this->graph->near_cols($mb);
		$mb = $near;
		$x = $this->graph->xAxis_value_to_x($mb);
		$pos = round_nobug($x * $this->factor_pos_x);

		$this->pos = $pos; //pos не совпадает с position если set_pos вызывается по событию "изменение" у трекбара

		// устанавливаем позиция трекбара, если изменилась
		if($this->trackbar->position != $pos) {
			// $log->line('Устанавливаем трекбар ' . $pos);
			$this->trackbar->position = $pos;
		}

		// устанавливаем ширину линии
		// да, нужно именно здесь, потому что иначе линия будет стоять а ползунок двигаться пока не дойдет до следующей ступени.
		$this->line_ui->w = $x - 1; // линия иногда залезает);

		// выделяем столбцы на графике
		$sum_select = $this->graph->select(0, $x, $is_redraw); 
		
		/* глючит в левой части графика, да и не нужен особо, так как мы по другому выделяем данные графике
		// делаем шаг равным stepKb
		if($mb) {
			$num_blocks = round_nobug($mb * 1024 / $this->stepKb);
			$mb = 0;
			if($num_blocks > 0)
				$mb = $num_blocks * $this->stepKb / 1024;
		}*/

		$this->mb = $mb;
		// осторожно здесь с округлением, цифры должны совпадать с тем что лежит в $this->mb
		$text = $Measure_convert->pretty_size($mb, 'MB', false); 
		if($this->graph->x_measure == 'speed')
			$text .= "/s";
		$this->info1->set_text($text);

		// сумма выделенных строк
		$sum_select_text = $Measure_convert->pretty_size($sum_select, 'MB', false); 
		$this->info2->set_text($sum_select_text);

		//$log->line(__method__ . ' start onChange');
		$this->onChange();
		//$log->line(__method__ . ' end onChange');
		//$log->line($text . "\tpos $pos\tx $x");

		return $pos; // возвращаем реально установленную позицию
	}

	// это генерируемом событие при set_pos или set_mb, его не надо самому вызывать
	function onChange() {}



	// проверяет, есть ли в столбцах справа от ползунка, данные
	static function check_right_pos($graph_name, $posMb) { 
		GLOBAL $INFO;

		// проверяем чтобы в график не был пустой
		// при загрузке программы это важно и может вызвать поток ненужных сообщений
		if(!$INFO[$graph_name] OR !array_sum($INFO[$graph_name]))
			return true; // поскольку график пустой, то любое значение ползунка верно

		foreach($INFO[$graph_name] as $pos=>$col_value) {
			if($pos >= $posMb) { // именно >=, это связано с особенностью наших графиков
				if($col_value > 0) {
					return true;
				}
			}
		}

		return false;
	}

	// ищем максимально правое значение для ползунка, так чтобы справа еще оставался один не пустой столбец 
	static function search_max_right_pos($graph_name) { 
		GLOBAL $INFO;

		$graph = $INFO[$graph_name];
		krsort($graph);

		$kray = false;
		foreach($graph as $pos=>$col_value) {
			if($col_value > 0) {
				return $pos;
				// if(!$kray)
				// 	$kray = true;
				// else
				// 	return $pos;
			}
		}

		return false;
	}
}




class Frags_select_bar extends Gr_select_bar {
	function onChange() {
		GLOBAL $INFO, $OP, $Graphs, $Ui_fields, $Ui_thread, $log;
		
		//$log->line(__method__ . ' ' . $this->get_mb());
		$Ui_fields['min_frag_size']->set($this->get_mb());

		/* все это заменили на строчку ниже, потому что любое изменение ползунка мне важно
		if($OP['analize_mode'] == 1)  {
#				$Graphs['speed']->view_msg_recalc('frags', 0);
		}
		elseif($OP['analize_mode'] == 2)  {
			//  актуальность информации в  графике фрагментов
				$Graphs['speed']->check_data_relevance('frags');
		}*/

		$Graphs['speed']->check_data_relevance('frags');


		// вычисляем frag
		$frag_sum = $Graphs['frags']->select_sumvalues;
		//$Graphs['disk']->set_col(GRD_frag, $frag_sum);
		$INFO[BLK_frag] = $frag_sum * 1024 / $OP['block_size'];

		//$INFO['BLK_frag_user_correct'] = $frag_sum - $INFO[BLK_frag];


		// что бы пересчет был в реальном времени
		Stat::redraw_block_status();
	}
}

class Speed_select_bar extends Gr_select_bar {
	function onChange() {
		GLOBAL $INFO, $Graphs, $Ui_fields, $Ui_thread, $OP, $log;
		
		$mb = $this->get_mb();
		//$log->line(__method__ . ' ' . $this->get_mb());
		$Ui_fields['analize_good_speed']->set($mb);
		//$log->line($this->get_mb());

#		if($OP['analize_mode'] == 1) {
			// отправляем инфу о суммен выделенных строк в график диска
			$sum_mb = $Graphs['speed']->select_sumvalues;
			$Graphs['disk']->set_col(GRD_all_slow, $sum_mb);

			//$log->line("sum_mb: $sum_mb");

			// обновляем информацию в info
			// делаем это только в простом режиме
			$sum_blocks = $sum_mb * 1024 / $OP['block_size'];
			$INFO[BLK_slow_analize] =
				$sum_blocks
				- $INFO[BLK_slow_read]
				- $INFO[BLK_antifrag]
				- $INFO[BLK_antifrag_cancel]
			;

			//$log->line("BLK_slow_analize: " . $INFO[BLK_slow_analize]);

/*
что входит в графика скоростей (все что имеет скорости):
на этапе чтения:	BLK_slow_read    BLK_antifrag  BLK_antifrag_cancel   BLK_fast  BLK_frag(на этапе анализа появляется, но они размазаны по всему графика, поэтому нельзя отнимать)
на этапе анализа: часть blk_fast преобразуются в blk_frag (считай read_block_fast - blk_fast).
*/

#		}	
#		elseif($OP['analize_mode'] == 2) {
			
#		}

		// актуальность информации в  графике скоростей
		// да, именно здесь, независимо от режима.
		// Иначе при некоторых условиях, сообщение о том что график надо обновить не пропадает после пересчета.
			$Graphs['frags']->check_data_relevance('speed'); 

		// что бы пересчет был в реальном времени
		Stat::redraw_block_status();
	}
}

?>