:- object capability_kernel : [bcilib, capability_lib, knowledge_base].

var actionDelay = 350.

proces_desires([]).

proces_desires([Desire|Rest]) :-
  proces_desire(Desire),
  proces_desires(Rest).
  
proces_desire(Desire) :-
%  format( 'Desire is ~w~n',[Desire]),
  capability(Desire, Conditions, Actions, Effects),
  conditions(Desire, Conditions, Actions, NewActions, Effects, NewEffects),
  actions(NewActions),
  effects(NewEffects),
  !.

conditions(Desire, [], Actions, Actions, Effects, Effects) :-
  delete_attr(desire, Desire),
  !.

conditions(Desire, [Condition|Rest], BeginActions, FinalActions, Effects, FinalEffects) :-
%  format('condition is ~w~n',[Condition]),
  condition(Condition, true, Actions),
  !,
  append(Actions, BeginActions, NewActions),
  conditions(Desire, Rest, NewActions, FinalActions, Effects, FinalEffects).

conditions(_Desire, [Condition|_], _Actions, Actions, _Effects, []) :-
  condition(Condition, false, Actions),
  !.

actions([]) :-
  !.

actions([fail|_]) :-
  !,
  fail.

actions([stop|_]) :-
  !.
  
actions([[]|Rest]) :-
  !,
  actions(Rest).

actions([action([Action|Arg])|Rest]) :-
  !,
  lookup_attr(belief, [name,Name]),
  Script =.. [Action, Name|Arg],
  step_kernel <- process_script(Script),
  actions(Rest).

actions([tell(String)|Rest]) :-
  !,
  teller <- output(String),
  actions(Rest).

actions([repeat(Action,Condition)|Rest]) :-
  !,
  repeat,
    actions(Action),
  condition(Condition, true, []),
  actions(Rest). 

%%% repeat(Actions, Condition, N, FailAction) %%%

var count=0.
actions([repeat(Actions, [Condition], N, FailAction)|Rest]) :-
  repeat,
    ++count,
    actions(Actions),
  continu_repeat(Condition, count >= N, FailAction, Rest, NewRest),
  actions(NewRest),
  !.

actions([if_then_else(Condition, Then, _Else)|Rest]) :-
  condition(Condition, true, []),
  !,
  append(Then, Rest, Actions),
  actions(Actions).

actions([if_then_else(Condition, _Then, Else)|Rest]) :-
  condition(Condition, false, []),
  !,
  append(Else, Rest, Actions),
  actions(Actions).

actions([or(Action1,_Action2)|Rest]) :-
  proces_desire(Action1),
  !,
  actions(Rest).
  
actions([or(_Action1,Action2)|Rest]) :-
  proces_desire(Action2),
  !,
  actions(Rest).

actions([Action|Rest]) :-
  proces_desire(Action),
  !,
  actions(Rest).

actions([Action|Rest]) :-
  rules <- rule(Action),
  !,
  actions(Rest).  

effects([]).

effects([add(Field, Effect)|Rest]) :-
  !,
  add_attr(Field, Effect),
  effects(Rest).

effects([delete(Field, Effect)|Rest]) :-
  !,
  delete_attr(Field, Effect),
  effects(Rest).

effects([add_list(Field, Item)|Rest]) :-
  !,
  delete_attr(Field, List),
  add_attr(Field, [Item|List]),
  effects(Rest).

effects([change(Field, Old, New)|Rest]) :-
  !,
  delete_attr(Field, Old),
  add_attr(Field, New),
  effects(Rest).

effects([increment(Field, Old, Amount)|Rest]) :-
  !,
  rules <- rule(increment(Old, Amount, New)),
  effects([change(Field, Old, New)|Rest]).

condition(property(Field, Term), Bool, Action) :-
  condition(property(Field, Term, []), Bool, Action).


condition(property(Field, Term, _Action), true, []) :-
  lookup_attr(Field, Term),
  !.

condition(property(Field, [F,Object|Args], Action), true, []) :-
  lookup_attr(Field, [Parent,Object]),
  condition(property(Field, [F,Parent|Args], Action), true, []).
  !.

condition(property(Field, not(Term), Action), true, []) :-
  !,
  condition(property(Field, Term, Action), false, _Action).

condition(property(Field, or(Term1,_Term2), Action), true, NewAction) :-
  condition(property(Field, Term1, Action), true, NewAction),
  !.
  
condition(property(Field, or(_Term1,Term2), Action), true, NewAction) :-
  condition(property(Field, Term2, Action), true, NewAction),
  !.

condition(property(Field, and(Term1,Term2), Action), true, NewAction) :-
  condition(property(Field, Term1, Action), true, Action1),
  condition(property(Field, Term2, Action), true, Action2),
  append(Action1,Action2,NewAction),
  !.

condition(property(Field, Term, try(TryAction)), true, []) :-
  actions([TryAction]),
  !,
  condition(property(Field, Term, []), true, []).
  
condition(property(Field, Term, Action), false, NewAction) :-
  member_attr_fail(Field, Term),
  get_false_action(Field, Term, Action, NewAction),
  !.

condition(child_property(Field, ChildField, Term), Bool, Action) :-
  condition(child_property(Field, ChildField, Term, []), Bool, Action).
  
condition(child_property(Field, ChildField, position(X,Y,Z), _Action), true, []) :-
  !,
  atom_list_concat([Field, '_', ChildField], NewField),
  getSFVec3f(NewField, translation, X,Y,Z).
  
condition(child_property(Field, ChildField, rotation(R), _Action), true, []) :-
  !,
  atom_list_concat([Field, '_', ChildField], NewField),
  getRotation(NewField, _X,_Y,_Z,R).
  
condition(child_property(Field, ChildField, status(Status), _Action), true, []) :-
  !,
  atom_list_concat([Field, '_', ChildField], NewField),
  format('newfield is ~w~n',[NewField]),
  getSFBool(NewField, status, Status),
  format('status is ~w~n',[Status]).

condition(child_property(Field, ChildField, Term, Action), false, NewAction) :-
  atom_list_concat([Field, '_', ChildField], NewField),
  get_false_action(NewField, Term, Action, NewAction),
  !.

condition(or(Condition1, _Condition2), true, Action) :-
  condition(Condition1, true, Action),
  !.
  
condition(or(_Condition1, Condition2), true, Action) :-
  condition(Condition2, true, Action),
  !.

condition(or(Condition1, Condition2), false, NewAction) :-
  condition(Condition1, false, Action1),
  condition(Condition2, false, Action2),
  append(Action1,Action2,NewAction),
  !.

condition(and(Condition1, Condition2), true, NewAction) :-
  condition(Condition1, true, Action1),
  condition(Condition2, true, Action2),
  append(Action1,Action2,NewAction),
  !.

condition(and(Condition1, Condition2), false, NewAction) :-
  condition(Condition1, false, Action1),
  condition(Condition2, false, Action2),
  append(Action1,Action2,NewAction),
  !.

condition(and(Condition1, _Condition2), false, Action1) :-
  condition(Condition1, false, Action1),
  !.

condition(and(_Condition1, Condition2), false, Action2) :-
  condition(Condition2, false, Action2),
  !.
  
condition(bool(Term, _Action), true, []) :-
  call(Term),
  !.

condition(bool(Term, Action), false, NewAction) :-
  get_false_action(_Field, Term, Action, NewAction),
  !.

continu_repeat(Condition1, _Condition2, _Action, Rest, Rest) :-
  condition(Condition1, true, []),
  !.
  
continu_repeat(_Condition1, Condition2, Action, _Rest, [Action]) :-
  call(Condition2),
  !.

get_false_action(_Field, _Term, [], []) :-
  !.
get_false_action(_Field, _Term, tell(Action), [tell(Action)]) :-
  !.
get_false_action(_Field, _Term, fail, [fail]) :-
  !.
get_false_action(_Field, _Term, _Action, []) :-
  !.
    
:- end_object capability_kernel.
