%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Aditivní a multiplikativní pravidla
% rules_cemera.pl
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% základní pravidla
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% anti quick pravidlo potlačuje nevybrané kamery
mult_camera_rule(Name, Time, Camera, Weight) :-
  Name = 'c_anti_quick',
  last_output_optimized(Time, LastCamera, HowLong),
  Camera \== LastCamera,
  rule_configuration(Name, Minimum, Maximum),
  ((HowLong < Minimum) ->
    Weight is 0;
    (camera_exp_base(Base),
     Weight is 1 - (cos((1 - exp(-Base * ((HowLong - Minimum) / (Maximum - Minimum)))) * pi) + 1) / 2
    )
  ).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% anti lazy pravidlo potlačuje vybranou kameru
mult_camera_rule(Name, Time, Camera, Weight) :-
  Name = 'c_anti_lazy',
  last_output_optimized(Time, LastCamera, HowLong),
  Camera == LastCamera,
  rule_configuration(Name, Minimum, Maximum),
  ((HowLong < Minimum) ->
    Weight is 1;
    (camera_exp_base(Base),
     MinWeight is 0.00001,
     Weight is max(1 - (cos((exp(-Base * ((HowLong - Minimum) / (Maximum - Minimum)))) * pi) + 1) / 2, MinWeight)
    )
  ).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 99% maximalní hodnoty pravidla
camera_exp_base(X) :-
  X is -log(0.01).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% potlačení přepnutí kamer v krátkem intervalu
add_camera_rule(Name, Time, Camera, Weight) :-
  Name = 'c_anti_swap',
  rule_configuration(Name, Minimum),
  last_output_optimized(Time, LastCamera, HowLong),
  LastCamera = Camera,
  HowLong < Minimum,
  Weight is 1.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% konstantná aditivná pravidlo
add_camera_rule(Name, _, Camera, Weight) :-
  Name = 'c_const',
  rule_configuration_dynamic(Name, Camera, Weight).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% konstantná aditivná pravidlo v dane stavu modelu
add_camera_rule(Name, _, Camera, Weight) :-
  Name = 'c_const_model',
  rule_configuration(Name, Camera, Weight, State),
  model_state(State).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% konstantná aktivita všem kamerám na začátku pořadu
add_camera_rule(Name, _, Camera, Weight) :-
  Name = 'c_initial_random_camera',
  rule_configuration(Name),
  not(is_empty_camera(Camera)),
  not(output(_, _, _)),
  Weight is 1.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% konstantní aktivita všem kamerám během pořadu => náhodné přepínaní
add_camera_rule(Name, _, Camera, Weight) :-
  Name = 'c_random_camera',
  rule_configuration(Name),
  not(is_empty_camera(Camera)),
  Weight is 1.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% vyhodnocení aktivity osob
add_camera_rule(Name, Time, Camera, Weight)  :-
  Name = 'c_person_activity',
  rule_configuration(Name),
  not(is_empty_camera(Camera)),
  findall(X, (person_activity(Time, Person, Activity),
	      (   Activity > 0
	      ->  person_visible(Time, Person, Camera, Percent)
	      ;   Percent is 0
	      ),
	      X is Activity * Percent), Weights),
  ((Weights = []) -> fail; sumlist(Weights, Sum)),
  person_count(Count),
  Weight is Sum / Count.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% podpora virtualních kamer / detailních záběrů
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% potlačení virtualních kamer na začátku pořadu
mult_camera_rule(Name, _, Camera, Weight) :-
  Name = 'c_virtual_supress_first',
  rule_configuration(Name),

%  camera(Camera, _, _, _, _, Parent, _),
%  Parent \== Camera,
  parent_camera(Camera, _),
  
  not(output(_, _, _)),
  Weight is 0.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% aplikace stejného anti lazy pravidla na korespondujécé fyzickou kameru
% kamery virtuální
mult_camera_rule(Name, Time, Camera, Weight) :-
  Name = 'c_virtual_parent_anti_lazy',
  rule_configuration(Name),
  last_output_optimized(Time, LastCamera),

%  camera(LastCamera, _, _, _, _, LastParent, _),
%  LastCamera \== LastParent,
  parent_camera(LastCamera, LastParent),
 
  Camera == LastParent,
  mult_camera_rule('c_anti_lazy', Time, LastCamera, Weight).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% potlačení ostatních virtualních kamer na stejné fyzické kameře
mult_camera_rule(Name, Time, Camera, Weight) :-
  Name = 'c_virtual_supress_same_parent',
  rule_configuration(Name),
  
%  camera(Camera, _, _, _, _, Parent, _),
%  Parent \== Camera,
  parent_camera(Camera, Parent),
  
  last_output_optimized(Time, LastCamera),
  Camera \== LastCamera,
  
%  camera(LastCamera, _, _, _, _, LastParent, _),
%  LastCamera \== LastParent,
  parent_camera(LastCamera, LastParent),
   
  Parent == LastParent,
  Weight is 0.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% potlačení ostatních virtuálních kamer na jiné fyzické kameře
% kromě dialogových dvojic
mult_camera_rule(Name, Time, Camera, Weight) :-
  Name = 'c_virtual_supress_other_parent',
  rule_configuration(Name),

%  camera(Camera, _, _, _, _, Parent, _),
%  Parent \== Camera,
  parent_camera(Camera, Parent),

  last_output_optimized(Time, LastCamera),
  Parent \== LastCamera,
  Camera \== LastCamera,

  (   pred_last_output(Time, LastCamera, PredCamera, _)
  ->  PredCamera \== Camera
  ;   true
  ),
  Weight is 0.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% potlačení virtuálních kamer na právě vybrané fyzické kameře
mult_camera_rule(Name, Time, Camera, Weight) :-
  Name = 'c_virtual_supress_parent',
  rule_configuration(Name, Parent),
  camera(Camera, _, _, _, _, Parent, _),
  Parent \== Camera,
  Weight is 0.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% pravidla pro podporu modelu pořadu
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% potlačení virtuálních kamer v úvodu / detailních záběrů
mult_camera_rule(Name, _, Camera, Weight) :-
  Name = 'c_intro_virtual_supress',
  rule_configuration(Name),
  model_state(intro),

%  is_virtual_camera(Camera),
  parent_camera(Camera, _),
  
  Weight is 0.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% potlačení virtuálních kamer v závěru / detailních záběrů
mult_camera_rule(Name, _, Camera, Weight) :-
  Name = 'c_finish_virtual_supress',
  rule_configuration(Name),
  model_state(finish),
  
%  is_virtual_camera(Camera),
  parent_camera(Camera, _),
  
  Weight is 0.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% zobrazení všech kamer v úvodu
add_camera_rule(Name, Time, Camera, Weight) :-
  Name = 'c_intro_physical',
  rule_configuration(Name),
  model_state(intro),
  not(is_empty_camera(Camera)),
  (setof(C, T^L^(output(T, C, L), T < Time), Cameras) -> true; Cameras = []),
  not(member(Camera, Cameras)),
  (add_camera_rule('c_person_activity', Time, Camera, PW) -> true; PW is 0),
  Weight is 2 * (1 - PW).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% zobrazení všech kamer v úvodu
mult_camera_rule(Name, Time, Camera, Weight) :-
  Name = 'c_intro_physical',
  rule_configuration(Name),
  model_state(intro),
  not(is_empty_camera(Camera)),
  (setof(C, T^L^(output(T, C, L), T < Time), Cameras) -> true; Cameras = []),
  member(Camera, Cameras),
  Weight is 0.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% podpora sumarizace
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% potlačení sumarizační kamery v úvodu
mult_camera_rule(Name, _, Camera, Weight) :-
  Name = 'c_summarization_supress',
  rule_configuration(Name),
  Camera = -1,
  not(output(_, _, _)),
  Weight is 0.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% sumarizace varianta 1
add_camera_rule(Name, Time, Camera, Weight) :-
  Name = 'c_summarization1',
  Camera = -1,
  rule_configuration(Name, TH1),
  (temp_configuration(Name, TH2) -> Treshold = TH2; Treshold = TH1),
  findall(A, person_activity(Time, _, A), Activities),
  sumlist(Activities, Sum),
  person_count(Count),
  W is Sum / Count,
  Weight is (1 - W) * Treshold.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% sumarizace varianta 2
add_camera_rule(Name, Time, Camera, Weight) :-
  Name = 'c_summarization2',
  Camera = -1,
  rule_configuration(Name, TH1),
  (temp_configuration(Name, TH2) -> Treshold = TH2; Treshold = TH1),
  findall(A, person_activity(Time, _, A), Activities),
  sumlist(Activities, Sum),
  person_count(Count),
  W is Sum / Count,
  W < Treshold,
  Weight is 1.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% sumarizace varianta 3
add_camera_rule(Name, Time, Camera, Weight) :-
  Name = 'c_summarization3',
  Camera = -1,
  rule_configuration(Name, TH1),
  (temp_configuration(Name, TH2) -> Treshold = TH2; Treshold = TH1),

  findall(A1, person_activity(Time, _, A1), Activities1),
  sumlist(Activities1, Sum1),
  person_count(Count),
  W1 is Sum1 / Count,

  step(Step),
  T2 is Time - Step,
  findall(A2, person_activity(T2, _, A2), Activities2),
  sumlist(Activities2, Sum2),
  W2 is Sum2 / Count,

  Weight is (1 - abs(W1 - W2)) * Treshold.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% sumarizace varianta 4
add_camera_rule(Name, Time, Camera, Weight) :-
  Name = 'c_summarization4',
  Camera = -1,
  rule_configuration(Name),
  
  findall(X, (person_activity(Time, Person, Activity), X is Activity), Weights),
  sumlist(Weights, S),
  S = 0,
  
  Weight is 100.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% pravidlo přepínání slajdů z minulých dat (exponenciální)
add_camera_rule(Name, Time, Camera, Weight) :-
  Name = 'c_past_slide_exp',
  rule_configuration(Name, MaxTime),
  is_silverscreen_camera(Camera),
  bagof(T, (slide_exchange(T, Camera), T =< Time, T > Time - MaxTime), L), 
  maxlist(L, LastSlide),
  HL is MaxTime - (Time - LastSlide),
  speaking_exp_base(Base),
  Weight is 1 - exp(-(Base * (HL / MaxTime))).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% pravidlo přepínání slajdů z budoucích dat (exponenciální)
add_camera_rule(Name, Time, Camera, Weight) :-
  Name = 'c_future_slide_exp',
  rule_configuration(Name, MaxTime),
  is_silverscreen_camera(Camera),
  bagof(T, (slide_exchange(T, Camera), T > Time, T =< Time + MaxTime), L), 
  minlist(L, NextSlide),
  HL is (NextSlide - Time),
  speaking_exp_base(Base),
  Weight is 1 - exp(-(Base * ((MaxTime - HL) / MaxTime))).
