#!/bin/bash
#Synchronize EnumToStringx.cpp and StringToEnumx.cpp and matlab Enums

#Get all lines of EnumDefinitions2.h which hold Enum | remove all commas > put everything in file temp
cat EnumDefinitions.h | grep -e "[0-9]Enum," -e "[a-zA-Z]Enum," -e "MaximumNumberOfDefinitionsEnum" | grep -v include | sed -e "s/,/ /g" | awk '{print $1}' > temp

#Removed existing files
rm $ISSM_DIR/src/m/enum/*.m
rm $ISSM_DIR/src/m/enum/*.py
rm $ISSM_DIR/src/c/shared/Enum/EnumToStringx.cpp
rm $ISSM_DIR/src/c/shared/Enum/StringToEnumx.cpp

#Get number of enums
NUMENUMS=$(wc -l temp | awk '{printf("%s",$1);}');

#Build EnumToStringx.cpp {{{
#Header
cat <<END >  $ISSM_DIR/src/c/shared/Enum/EnumToStringx.cpp
/*
* \file EnumToStringx.cpp:
* \brief: output string associated with enum
*
*   WARNING: DO NOT MODIFY THIS FILE
*            this file has been automatically generated by Synchronize.sh
*            Please read README for more information
*/

#include <cstring>
#include "./Enum.h"
#include "../Exceptions/exceptions.h"
#include "../MemOps/MemOps.h"

const char* EnumToStringx(int en){

	switch(en){

END
#core
cat temp |  awk '{print "\t\t" "case " $1" : return \"" substr($1,1,length($1)-4) "\";"}' >> $ISSM_DIR/src/c/shared/Enum/EnumToStringx.cpp
#Footer
cat <<END >> $ISSM_DIR/src/c/shared/Enum/EnumToStringx.cpp
		default : return "unknown";

	}
}
void EnumToStringx(char** pstring,int enum_in){
	char *string = NULL;
	int   len = 0;

	len=strlen(EnumToStringx(enum_in));
	string=xNew<char>(len+1);
	memcpy(string,EnumToStringx(enum_in),(len+1)*sizeof(char));

	/*Assign output pointer*/
	*pstring=string;
}
END
#}}}
#Build StringToEnumx.cpp {{{
#Header
cat <<END > $ISSM_DIR/src/c/shared/Enum/StringToEnumx.cpp
/*
* \file StringToEnumx.cpp:
* \brief: output enum associated with string
*
*   WARNING: DO NOT MODIFY THIS FILE
*            this file has been automatically generated by Synchronize.sh
*            Please read README for more information
*/

#include <cstring>
#include "./Enum.h"
#include "../Exceptions/exceptions.h"

int  StringToEnumx(const char* name,bool notfounderror){

   int  stage=1;

END

#core
i1=1;
i2=120;
for (( i=1 ; i<=100 ; i++ )); do
	echo "   if(stage==$i){" >> $ISSM_DIR//src/c/shared/Enum/StringToEnumx.cpp
	awk -v i1=$i1 -v i2=$i2 '{if(NR>=i1 && NR<=i2) print $0 }' temp |
	awk '{print "\t" ((NR==1)?"      if":"      else if") " (strcmp(name,\"" substr($1,1,length($1)-4) "\")==0) return " $1 ";"}' >> $ISSM_DIR//src/c/shared/Enum/StringToEnumx.cpp
	echo "         else stage=$(($i+1));" >> $ISSM_DIR//src/c/shared/Enum/StringToEnumx.cpp
	echo "   }" >> $ISSM_DIR//src/c/shared/Enum/StringToEnumx.cpp
	
	if [ $i2 -ge $NUMENUMS ]; then break; fi
	let i1=$i1+120
	let i2=$i2+120
done

#footer
cat <<END >> $ISSM_DIR/src/c/shared/Enum/StringToEnumx.cpp
	/*If we reach this point, the string provided has not been found*/
	if(notfounderror)
		_error_("Enum " << name << " not found");
	else
		return -1;
}
END
#}}}
#Build EnumToAnalysis.cpp {{{
#Header
cat <<END > $ISSM_DIR/src/c/analyses/EnumToAnalysis.cpp
/*
* \file EnumToAnalysis.cpp
* \brief: output class depending on enum
*
*   WARNING: DO NOT MODIFY THIS FILE
*            this file has been automatically generated by Synchronize.sh
*            Please read README for more information
*/

#include "./analyses.h"
#include "../shared/shared.h"

Analysis* EnumToAnalysis(int analysis_enum){

	switch(analysis_enum){
END
#core
cat temp | grep [a-zA-Z]Analysis | \
	grep -v DefaultAnalysis | grep -v FlaimAnalysis | grep -v SurfaceSlopeAnalysis | grep -v BedSlopeAnalysis | \
	awk '{print "\t\t#ifdef _HAVE_"toupper(substr($1,1,length($1)-12))"_\n\t\t" "case " $1" : return new " substr($1,1,length($1)-4) "();\n\t\t#endif"}' \
		>> $ISSM_DIR/src/c/analyses/EnumToAnalysis.cpp

#Footer
cat <<END >> $ISSM_DIR/src/c/analyses/EnumToAnalysis.cpp
		default : _error_("enum provided not supported ("<<EnumToStringx(analysis_enum)<<")");
	}
}
END
#}}}
#Build EnumDefinitions.py{{{
cat <<END > $ISSM_DIR/src/m/enum/EnumDefinitions.py
from StringToEnum import StringToEnum

"""

WARNING: DO NOT MODIFY THIS FILE
this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
Please read src/c/shared/Enum/README for more information

"""

END
#core
cat temp |  awk '{print "def " $1"(): return StringToEnum(\"" substr($1,1,length($1)-4) "\")[0]"}' >> $ISSM_DIR/src/m/enum/EnumDefinitions.py
#}}}

# go through the lines of temp
ENUM=0;

for NAMEENUM in $(cat temp); do

	#Get name and enum of the line i
	NAME=$(echo $NAMEENUM | sed -e "s/Enum//g")
	#offset Enum by one (Enum begins with 0 and not 1!)
	let ENUM=$ENUM+1

	#print info {{{
	if [ $ENUM -lt 10 ]
	then
		printf "\r                                                                      "
		printf "\r  $ENUM/$NUMENUMS Adding "$NAME"..."
	else
		if [ $ENUM -lt 100 ]
		then
			printf "\r                                                                      "
			printf "\r $ENUM/$NUMENUMS Adding "$NAME"..."
		else
			printf "\r                                                                      "
			printf "\r$ENUM/$NUMENUMS Adding "$NAME"..."
		fi
	fi
	#}}}
	#Add case to matlabenum file{{{
	cat <<END > $ISSM_DIR"/src/m/enum/"$(echo $NAMEENUM".m")
function macro=$(echo $NAMEENUM)()
%$(echo $NAMEENUM | awk {'print toupper($1)'}) - Enum of $(echo $NAME)
%
%   WARNING: DO NOT MODIFY THIS FILE
%            this file has been automatically generated by src/c/shared/Enum/Synchronize.sh
%            Please read src/c/shared/Enum/README for more information
%
%   Usage:
%      macro=$NAMEENUM()

macro=StringToEnum('$NAME');
END
#}}}

done
#clean up{{{
rm temp
#}}}
#print info {{{
printf "\r                                                                      "
printf "\rdone!\n"
#}}}
