%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Manipulace s objekty hlav
% head.pl
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
init_head:-
  retractall(head_move(_, _, _, _)),
  (   test_mode([offline, half_realtime]) 
  ->  write_begin('generating head_move'),
      begin(B),
      end(E),
      step(S),
      ignore(generate_all_head_move_step(B, E, S)),
      write_done
  ;   true
  ).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% základní fakta
head(Time, Camera, Person) :-
  head(Time, Camera, _, _, _, _, _, _, _, Person).
head(Time, Camera, Person, CenterX, CenterY) :-
  head(Time, Camera, _, CenterX, CenterY, _, _, _, _, Person).
head(Time, Camera, Object, Person, CenterX, CenterY) :-
  head(Time, Camera, Object, CenterX, CenterY, _, _, _, _, Person).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% vzdálenost mezi dvěma pozicemi stejného objektu
get_head_move(Time, Step, Camera, Person, Move) :-
  head(Time, Camera, Object, Person, CenterX, CenterY),
  Time2 is Time + Step,
  head(Time2, Camera, Object, Person, CenterX2, CenterY2),
  Move is sqrt((CenterX2 - CenterX) ** 2 + (CenterY2 - CenterY) ** 2).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% generování pomocných faktů
generate_all_head_move_step(Time, End, Step):-
  (   Time =< End
  ->  ignore(generate_all_head_move(Time, Step)),
      T is Time + Step,
      generate_all_head_move_step(T, End, Step)
  ).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
generate_all_head_move(Time, Step):-
  forall((bagof(Move, get_head_move(Time, -Step, Camera, Person, Move), Moves),
	  averlist(Moves, Aver)),
	 assert(head_move(Time, Camera, Person, Aver))).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% posuny objektů v časovém okně
head_moves(Time, Step, Window, Camera, Person, Moves):-
  (Window =< 0) -> Moves = [];
  (T is Time + Step,
   W is Window - abs(Step),
   head_moves(T, Step, W, Camera, Person, M),
   (head_move(Time, Camera, Person, Move) -> Moves = [Move|M]; Moves = M)
  ).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% pozice objektů v časovém okně
head_positions(Time, Step, Window, Camera, Person, Positions):-
  (Window =< 0) -> Positions = [];
  (T is Time + Step,
   W is Window - abs(Step),
   head_positions(T, Step, W, Camera, Person, P),
   (head(Time, Camera, Person, CenterX, CenterY) -> Positions = [(CenterX, CenterY)|P]; Positions = P)
  ).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% pozice objektů v časovém okně
head_full_positions(Time, Direction, Window, Camera, Person, Positions):-
  (Window =< 0) -> Positions = [];
  (step(Step),
   T is Time + (Step * Direction),
   W is Window - abs(Step),
   head_full_positions(T, Direction, W, Camera, Person, P),
   (head(Time, Camera, _, CenterX, CenterY, MinX, MinY, MaxX, MaxY, Person) -> Positions = [(CenterX, CenterY, MinX, MinY, MaxX, MaxY)|P]; Positions = P)
  ).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
generate_head_full_positions(Direction, Window, Camera, Person) :-
  retractall(head_full_positions_static(_, Direction, Window, Camera, Person, _)),
  begin(B),
  end(E),
  step(S),
  ignore(generate_head_full_positions_step(Direction, Window, Camera, Person, B, E, S)),
  true.

generate_head_full_positions_step(Direction, Window, Camera, Person, Time, End, Step) :-
  (   Time =< End
  ->  ignore((head_full_positions(Time, Direction, Window, Camera, Person, LC),
      
	      findall(X, member((X, _, _, _, _, _), LC), Xs),
	      findall(Y, member((_, _, _, Y, _, _), LC), Ys),
	      averlist(Xs, X1),
	      averlist(Ys, Y1),

              assert(head_full_positions_static(Time, Direction, Window, Camera, Person, (X1, Y1)))    
	     )),
      T is Time + Step,
      generate_head_full_positions_step(Direction, Window, Camera, Person, T, End, Step)
  ).

