%% =====================================================================
%% Refactoring: Prova
%% =====================================================================

-module(refac2_Lista).

-export([refac_Lista/1, refac_Lista_eclipse/1]).

%-import(refac_atom_utils, [output_atom_warning_msg/3,check_atoms/4,start_atom_process/0,stop_atom_process/1]).

-include("../include/wrangler.hrl").

-spec(refac_Lista/1::(filename()) -> 
	     {error, string()} | {question, string()} |{ok, [filename()], boolean()}).
refac_Lista(FileName) ->
    refac_Lista(FileName,emacs).

-spec(refac_Lista_eclipse/1::(filename()) ->
	     {error, string()} | {question, string()} | {warning, string()} |
		 {ok, [{filename(), filename(), string()}]}).
refac_Lista_eclipse(FileName) ->
    refac_Lista(FileName,eclipse).


refac_Lista(FileName,Editor) ->

	{ok,X} = smerl:for_file(FileName),
	NXX = smerl:set_forms(X,lists:reverse(applyRefacLlistaFun(smerl:get_forms(X)))),
	smerl:to_src(NXX,FileName),
	{ok,[]}.


%****************************************************************************** 
%*************   applyRefacLlistaFun   *****************************
%******************************************************************************
applyRefacLlistaFun([])->[];
applyRefacLlistaFun([{function,LINE,Name,Arity,Clauses}|Funs]) ->
	NewClauses = applyRefac_clausesGeneric(Clauses),
	[{function,LINE,Name,Arity,NewClauses}|applyRefacLlistaFun(Funs)];
applyRefacLlistaFun(Other)->
	Other.

%****************************************************************************** 
%*************   applyRefac_clausesGeneric *****************************
%******************************************************************************
applyRefac_clausesGeneric([]) -> [];
applyRefac_clausesGeneric([{clause,LINE,Patterns,Guards,Body}|Clauses])->
	NBody = applyRefac_expressionsGeneric(Body),
	NPatterns = applyRefac_expressionsGeneric(Patterns),
	NGuards = applyRefac_expressionsGeneric(Guards),
	[{clause,LINE,NPatterns,NGuards,NBody}|applyRefac_clausesGeneric(Clauses)];
applyRefac_clausesGeneric(Other)->
	Other.

%****************************************************************************** 
%*************   applyRefac_expressionsGeneric  *****************************
%******************************************************************************
applyRefac_expressionsGeneric([])->[];
applyRefac_expressionsGeneric([Exp|Exps]) ->
	[applyRefac_expressionGeneric(Exp)|applyRefac_expressionsGeneric(Exps)];
applyRefac_expressionsGeneric(Other)->
	applyRefac_expressionGeneric(Other).




%****************************************************************************** 
%*************   applyRefac_expressionGeneric  *****************************
%******************************************************************************
%applyRefac_expressionGeneric({var,LINE,V}) ->	
%	{var,LINE,list_to_atom(lists:append(atom_to_list(V),"x"))};
applyRefac_expressionGeneric({match,LINE,E1,E2})->
	{match,LINE,applyRefac_expressionsGeneric(E1),
	 applyRefac_expressionsGeneric(E2)};
applyRefac_expressionGeneric({tuple,LINE,Exps})->
	{tuple,LINE,applyRefac_expressionsGeneric(Exps)};
applyRefac_expressionGeneric({cons,LINE,E1,E2})->
	{cons,LINE,applyRefac_expressionsGeneric(E1),
	 applyRefac_expressionsGeneric(E2)};

applyRefac_expressionGeneric({op,LINE,'++',{cons,_,E1,{nil,_}},E2})->
		{cons,LINE,applyRefac_expressionGeneric(E1),applyRefac_expressionsGeneric(E2)};
applyRefac_expressionGeneric({op,_,'++',{nil,_},E2})->
		applyRefac_expressionsGeneric(E2);
applyRefac_expressionGeneric({op,_,'++',E1,{nil,_}})->
		applyRefac_expressionsGeneric(E1);
applyRefac_expressionGeneric({op,LINE,'++',{string,_,[C]},{string,_,E2}})->
		{string,LINE,[C|E2]};
applyRefac_expressionGeneric({op,LINE,'++',{string,_,""},{string,_,E2}})->
		{string,LINE,E2};
applyRefac_expressionGeneric({op,LINE,'++',{string,_,E1},{string,_,""}})->
		{string,LINE,E1};
	
applyRefac_expressionGeneric({op,LINE,Op,E1,E2})->
	{op,LINE,Op,applyRefac_expressionsGeneric(E1),
	 applyRefac_expressionsGeneric(E2)};
applyRefac_expressionGeneric({op,LINE,Op,E})->
	{op,LINE,Op,applyRefac_expressionsGeneric(E)};

applyRefac_expressionGeneric({record,LINE,Name,RecordFields})->
	{record,LINE,Name,applyRefac_expressionsGeneric(RecordFields)};
applyRefac_expressionGeneric({record,LINE,E0,Name,RecordFields})->
	{record,LINE,applyRefac_expressionsGeneric(E0),Name,applyRefac_expressionsGeneric(RecordFields)};
applyRefac_expressionGeneric({record_index,LINE,Name,Field})->
	{record_index,LINE,Name,applyRefac_expressionsGeneric(Field)};
applyRefac_expressionGeneric({record_field,LINE,E0,Field})->
	{record_field,LINE,applyRefac_expressionsGeneric(E0),applyRefac_expressionsGeneric(Field)};
applyRefac_expressionGeneric({record_field,LINE,E0,Name,Field})->
	{record_field,LINE,applyRefac_expressionsGeneric(E0),Name,applyRefac_expressionsGeneric(Field)};

applyRefac_expressionGeneric({'catch',LINE,E})->
	{'catch',LINE,applyRefac_expressionsGeneric(E)};

applyRefac_expressionGeneric({call,LINE,{remote,LINE,{atom,_,lists},{atom,_,append}},[{cons,_,E1,{nil,_}},E2]})->
	{cons,LINE,applyRefac_expressionGeneric(E1),applyRefac_expressionsGeneric(E2)};
applyRefac_expressionGeneric({call,LINE,{remote,LINE,{atom,_,lists},{atom,_,append}},[{nil,_},E2]})->
	applyRefac_expressionsGeneric(E2);
applyRefac_expressionGeneric({call,LINE,{remote,LINE,{atom,_,lists},{atom,_,append}},[E1,{nil,_}]})->
	applyRefac_expressionsGeneric(E1);
applyRefac_expressionGeneric({call,LINE,{remote,LINE,{atom,_,lists},{atom,_,append}},[{string,_,[C]},{string,_,E2}]})->
	{string,LINE,[C|E2]};
applyRefac_expressionGeneric({call,LINE,{remote,LINE,{atom,_,lists},{atom,_,append}},[{string,_,""},{string,_,E2}]})->
	{string,LINE,E2};
applyRefac_expressionGeneric({call,LINE,{remote,LINE,{atom,_,lists},{atom,_,append}},[{string,_,E1},{string,_,""}]})->
	{string,LINE,E1};

applyRefac_expressionGeneric({call,LINE,{remote,LINE,{atom,_,lists},{atom,_,substract}},[{nil,_},E2]})->
	{nil,LINE};
applyRefac_expressionGeneric({call,LINE,{remote,LINE,{atom,_,lists},{atom,_,substract}},[E1,{nil,_}]})->
	applyRefac_expressionsGeneric(E1);
applyRefac_expressionGeneric({call,LINE,{remote,LINE,{atom,_,lists},{atom,_,substract}},[{string,_,""},{string,_,E2}]})->
	{string,LINE,""};
applyRefac_expressionGeneric({call,LINE,{remote,LINE,{atom,_,lists},{atom,_,substract}},[{string,_,E1},{string,_,""}]})->
	{string,LINE,E1};
applyRefac_expressionGeneric({call,LINE,{remote,LINE,{atom,_,lists},{atom,_,substract}},[{cons,_,E1,E2},{cons,_,E3,E4}]})->
	({op,LINE,'--',{cons,LINE,E1,E2},{cons,LINE,E3,E4}});
applyRefac_expressionGeneric({call,LINE,{remote,LINE,{atom,_,lists},{atom,_,substract}},[{string,_,E1},{string,_,E2}]})->
	({op,LINE,'--',{string,LINE,E1},{string,LINE,E2}});


applyRefac_expressionGeneric({call,LINE,{remote,LINE,EM,EF},Exps})->
	{call,LINE,{remote,LINE,applyRefac_expressionsGeneric(EM),
	 applyRefac_expressionsGeneric(EF)},
	 applyRefac_expressionsGeneric(Exps)};
applyRefac_expressionGeneric({call,LINE,EF,Exps})->
	{call,LINE,applyRefac_expressionsGeneric(EF),
	 applyRefac_expressionsGeneric(Exps)};

applyRefac_expressionGeneric({block,LINE,E})->
	{block,LINE,applyRefac_expressionsGeneric(E)};
applyRefac_expressionGeneric({'if',LINE,Clasues})->
	{'if',LINE,applyRefac_clausesGeneric(Clasues)};
applyRefac_expressionGeneric({'case',LINE,E,Clasues})->
	{'case',LINE,applyRefac_expressionGeneric(E),
	applyRefac_clausesGeneric(Clasues)};
applyRefac_expressionGeneric({lc,LINE,E0,W})->
	{lc,LINE,applyRefac_expressionsGeneric(E0),applyRefac_expressionsGeneric(W)};
applyRefac_expressionGeneric({bc,LINE,E0,W})->
	{bc,LINE,applyRefac_expressionsGeneric(E0),applyRefac_expressionsGeneric(W)};

applyRefac_expressionGeneric({'try',LINE,B,[],[],A})->
	{'try',LINE,applyRefac_expressionsGeneric(B),[],[],applyRefac_expressionsGeneric(A)};
applyRefac_expressionGeneric({'try',LINE,B,[],C,[]})->
	{'try',LINE,applyRefac_expressionsGeneric(B),[],applyRefac_expressionsGeneric(C),[]};
applyRefac_expressionGeneric({'try',LINE,B,C,[],A})->
	{'try',LINE,applyRefac_expressionsGeneric(B),applyRefac_expressionsGeneric(C),[],applyRefac_expressionsGeneric(A)};
applyRefac_expressionGeneric({'try',LINE,B,[],C,A})->
	{'try',LINE,applyRefac_expressionsGeneric(B),[],applyRefac_expressionsGeneric(C),applyRefac_expressionsGeneric(A)};
applyRefac_expressionGeneric({'try',LINE,B,C,T,[]})->
	{'try',LINE,applyRefac_expressionsGeneric(B),applyRefac_expressionsGeneric(C),applyRefac_expressionsGeneric(T),[]};
applyRefac_expressionGeneric({'try',LINE,B,C,T,A})->
	{'try',LINE,applyRefac_expressionsGeneric(B),applyRefac_expressionsGeneric(C),applyRefac_expressionsGeneric(T),applyRefac_expressionGeneric(A)};

applyRefac_expressionGeneric({'fun',LINE,F})->
	{'fun',LINE,applyRefac_expressionsGeneric(F)};
applyRefac_expressionGeneric({'query',LINE,F})->
	{'query',LINE,applyRefac_expressionsGeneric(F)};
applyRefac_expressionGeneric({'receive',LINE,C})->
	{'receive',LINE,applyRefac_clausesGeneric(C)};
applyRefac_expressionGeneric({'receive',LINE,C,E,B})->
	{'receive',LINE,applyRefac_clausesGeneric(C),applyRefac_expressionsGeneric(E),applyRefac_expressionsGeneric(B)};
applyRefac_expressionGeneric({generate,LINE,P,E})->
	{generate,LINE,applyRefac_expressionsGeneric(P),applyRefac_expressionsGeneric(E)};
applyRefac_expressionGeneric({b_generate,LINE,P,E})->
	{b_generate,LINE,applyRefac_expressionsGeneric(P),applyRefac_expressionsGeneric(E)};

applyRefac_expressionGeneric({clauses,Clauses})->
	{clauses,applyRefac_clausesGeneric(Clauses)};

%Casos dels clause
applyRefac_expressionGeneric([A|B]) ->
	[applyRefac_expressionGeneric(A)|applyRefac_expressionsGeneric(B)];

applyRefac_expressionGeneric(Other)->
	Other.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

