# 
# $Id$
# 
# [ Description ]
# 
# Makefile
# 

#-----[ Variables ]----------------------------------------
DIR_BIN				= bin
DIR_LIB				= ../lib
DIR_CFG				= configuration
DIR_LOG				= log

CFG_FILE			= configuration.cfg

OBJECTS      			= $(OBJECTS_COMMON)

EXEC_LOG			= $(patsubst $(DIR_CFG)/%.cfg,$(DIR_LOG)/%.exec.log,$(wildcard $(DIR_CFG)/*.cfg))
EXEC				= soft

#-----[ Rules ]--------------------------------------------
.PRECIOUS			: $(DIR_BIN)/%.x $(DIR_LOG)/%.exec.log
.NOPARALLEL			: clean clean_all help

all_selftest   			: test_env $(DIR_OBJ) $(DIR_BIN) $(DIR_LOG)
				@$(MAKE) library
				@$(MAKE) $(DIR_BIN)/$(EXEC).x

execute				: all_selftest
				@$(MAKE) $(EXEC_LOG)

reconfig			:
				@$(MAKE) config_clean
				@$(MAKE) config

config_clean			:
				@													\
				declare     NAME;											\
				declare -i  CPT=0;											\
				declare -ai PERIOD;											\
				declare -a  RANGE_LOCAL;										\
				PERIOD[0]=1;												\
																	\
				while $(READ) line; do											\
				        LINE=($$line);											\
																	\
					if $(TEST) $$CPT -eq 0; then 									\
						NAME=$${LINE[0]};									\
					else												\
						RANGE_LOCAL=($$($(DIR_SCRIPT)/range.sh $${LINE[0]} $${LINE[1]} $${LINE[2]}));		\
						PERIOD[$$CPT]=$$(($${PERIOD[$$(($$CPT-1))]}*$${#RANGE_LOCAL[*]}));			\
					fi;												\
																	\
					CPT=$$(($$CPT+1));										\
				done < $(CFG_FILE);											\
																	\
				declare -i NB_CONFIG=$${PERIOD[$$(($$CPT-1))]};								\
																	\
				for i in $$($(DIR_SCRIPT)/range.sh 0 $$(($$NB_CONFIG-1))); do						\
					$(RM) "$(DIR_CFG)/$${NAME}_$${i}.cfg";								\
				done;

config        			:
				@$(ECHO) "Generate configuration"
				@													\
				declare     NAME;											\
				declare -ai MIN ;											\
				declare -ai MAX ;											\
				declare -a  STEP; 											\
				declare -a  LINE; 											\
				declare -i  CPT=0;											\
				declare -ai PERIOD;											\
				declare -a  RANGE;											\
				declare -a  RANGE_LOCAL;										\
				declare -a  SIZE;											\
				PERIOD[0]=1;												\
																	\
				while $(READ) line; do											\
				        LINE=($$line);											\
																	\
					if $(TEST) $$CPT -eq 0; then 									\
						NAME=$${LINE[0]};									\
					else												\
						MIN[$$CPT]=$${LINE[0]};									\
						MAX[$$CPT]=$${LINE[1]};									\
						STEP[$$CPT]=$${LINE[2]};								\
						RANGE[$$CPT]=$$($(DIR_SCRIPT)/range.sh $${LINE[0]} $${LINE[1]} $${LINE[2]});		\
						RANGE_LOCAL=($${RANGE[$$CPT]});								\
						SIZE[$$CPT]=$${#RANGE_LOCAL[*]};							\
						PERIOD[$$CPT]=$$(($${PERIOD[$$(($$CPT-1))]}*$${SIZE[$$CPT]}));				\
					fi;												\
																	\
					CPT=$$(($$CPT+1));										\
				done < $(CFG_FILE);											\
																	\
				declare -i x;												\
				declare -a DATA;											\
				declare -ai ENUM_CONFIG=($$($(DIR_SCRIPT)/range.sh 0 $$(($${PERIOD[$$(($$CPT-1))]}-1))));		\
				declare -ai ENUM_PARAM=($$($(DIR_SCRIPT)/range.sh 1 $${#MIN[*]}));            				\
																	\
 				$(ECHO) " * they are $${#MIN[*]} parameters";								\
 				$(ECHO) " * generate $${PERIOD[$$(($$CPT-1))]} configurations";						\
																	\
				for i in $${ENUM_CONFIG[*]}; do										\
					x=$$i;												\
					for j in $${ENUM_PARAM[*]}; do									\
						RANGE_LOCAL=($${RANGE[$$j]});								\
						DATA[$$j]="$${RANGE_LOCAL[$$((($$x % $${SIZE[$$j]})))]} ";				\
						x=$$(($$x/$${SIZE[$$j]})); 								\
					done;												\
					$(ECHO) $${DATA[*]} > "$(DIR_CFG)/$${NAME}_$${i}.cfg";						\
					$(ECHO) "  - {$$i} $${DATA[*]}";								\
				done;

$(DIR_LOG)/%.exec.log		: $(DIR_CFG)/%.cfg $(DIR_BIN)/$(EXEC).x
				@$(ECHO) "Execute            : $*"
				@$(EXPORT) SYSTEMC=$(SYSTEMC) ; ./$(DIR_BIN)/$(EXEC).x $(EXEC_PARAMS) $* `$(CAT) $<` > $@
				declare -i count=`$(GREP) -ch "Test KO" $@`;		\
				if $(TEST) $$count -eq 0;       			\
				then echo "                     $* ... OK";           	\
				else echo "                     $* ... KO"; exit 1;     \
				fi;

$(DIR_BIN)/%.x			: $(OBJECTS) $(HEADERS) $(DIR_LIB)
				@$(ECHO) "Linkage            : $*"
				@$(CXX) $(LXX_OPT) -o $@ $(OBJECTS) $(LIBS)

$(DIR_BIN)			:
				@$(ECHO) "Create directory   : $@"
				@$(MKDIR) $@

$(DIR_LOG)			:
				@$(ECHO) "Create directory   : $@"
				@$(MKDIR) $@

selftest_clean_all		: library_clean config_clean
				
selftest_clean			: 
				@$(RM) 	$(DIR_LOG)		\
					$(DIR_CFG)/*~		\
					*.vhdl			\
					*.stat			\
					generated_by_systemcass \
					core*

selftest_help			:
				@$(ECHO) " -----[ Selftest ]-----------------------------------"
				@$(ECHO) ""
				@$(ECHO) " * all_selftest         : compile all c++ file and execute"
				@$(ECHO) " * execute              : execute all instance"
				@$(ECHO) " * config               : generate configuration with configuration's file" 
				@$(ECHO) " * reconfig             : regenerate configuration with configuration's file" 
				@$(ECHO) " * clean                : Erase all generate files"
				@$(ECHO) " * clean_all            : Clean + Erase all dependant library"
				@$(ECHO) " * help                 : print this text"
				@$(ECHO) ""

help				: 
				@$(MAKE) common_help  
				@$(MAKE) synthesis_help  
				@$(MAKE) selftest_help

clean				: 
				@$(MAKE) common_clean 
				@$(MAKE) synthesis_clean 
				@$(MAKE) selftest_clean

clean_all			: 
				@$(MAKE) clean 
				@$(MAKE) selftest_clean_all
