#!/bin/bash
################################################################################
# Synchronize EnumToStringx.cpp and StringToEnumx.cpp and MATLAB Enums
#
# Get all lines of EnumDefinitions.h which hold Enum | remove all commas > put everything in file temp
#
# NOTE: Even when run from this directory, ISSM_DIR must be defined correctly.
#
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/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);}');

#Deal with Analyses
if false; then
#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-Z0-9]Analysis | \
	grep -v DefaultAnalysis | grep -v RecoveryAnalysis | 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 analyses.m4{{{
#Header
cat <<END > $ISSM_DIR/m4/analyses.m4

dnl   WARNING: DO NOT MODIFY THIS FILE
dnl            this file has been automatically generated by Synchronize.sh
dnl            Please read README for more information

# AX_ANALYSES_SELECTION
# -----------------
# Check for analyses compilation
AC_DEFUN([AX_ANALYSES_SELECTION],
[

END
#core
cat temp | grep [a-zA-Z0-9]Analysis | \
	grep -v DefaultAnalysis | grep -v FlaimAnalysis | grep -v SurfaceSlopeAnalysis | grep -v BedSlopeAnalysis | \
	sed -e "s/AnalysisEnum//g" | \
	awk '{print "dnl with-" $1"{{{\n\
AC_ARG_WITH([" $1"],\n\
\tAS_HELP_STRING([--with-" $1" = YES], [compile with " $1" capabilities (default is yes)]),\n\
\t[" toupper($1)"=$withval],[" toupper($1)"=yes])\n\
AC_MSG_CHECKING(for " $1" capability compilation)\n\n\
HAVE_"  toupper($1)"=no \n\
if test \"x$"  toupper($1)"\" = \"xyes\"; then\n\
	HAVE_"  toupper($1)"=yes\n\
	AC_DEFINE([_HAVE_"  toupper($1)"_],[1],[with " $1" capability])\n\
fi\n\
AM_CONDITIONAL([" toupper($1)"], [test x$HAVE_" toupper($1)" = xyes])\n\
AC_MSG_RESULT($HAVE_" toupper($1)")\n\
dnl }}}"}' \
	>> $ISSM_DIR/m4/analyses.m4

#Footer
cat <<END >> $ISSM_DIR/m4/analyses.m4

])
END
#}}}
fi

#Enum to String conversions
#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;
}

bool IsInputEnum(int enum_in){
	if(enum_in>InputsSTARTEnum && enum_in<InputsENDEnum) return true;
	return false;
}

bool IsParamEnum(int enum_in){
	if(enum_in>ParametersSTARTEnum && enum_in<ParametersENDEnum) return true;
	return false;
}
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 issmenum.jl {{{
#Header
cat <<END >  $ISSM_DIR/src/c/shared/Enum/issmenums.jl
#   WARNING: DO NOT MODIFY THIS FILE
#            this file has been automatically generated by Synchronize.sh
#            Please read README for more information

@enum IssmEnum begin
END
cat temp |  awk '{print "\t" $1}' >> $ISSM_DIR/src/c/shared/Enum/issmenums.jl
#Move on to EnumToString
cat <<END >> $ISSM_DIR/src/c/shared/Enum/issmenums.jl
end

function EnumToString(enum::IssmEnum)
END
cat temp |  awk '{print "\tif(enum==" $1 ") return \"" substr($1,1,length($1)-4) "\" end"}' >> $ISSM_DIR/src/c/shared/Enum/issmenums.jl
#Move on to StringToEnumx
cat <<END >> $ISSM_DIR/src/c/shared/Enum/issmenums.jl
end

function StringToEnum(name::String)
END
cat temp |  awk '{print "\tif(name==\"" substr($1,1,length($1)-4) "\") return " $1 "  end"}' >> $ISSM_DIR/src/c/shared/Enum/issmenums.jl

cat <<END >> $ISSM_DIR/src/c/shared/Enum/issmenums.jl
	error("Enum ", name, " not found");
end
END
#}}}
#Build listoutputs.m {{{
#Header
cat <<END >  $ISSM_DIR/src/m/solve/listoutputs.m
%   List possible outputs to be requested
%
%   WARNING: The outputs that are actually available in a simulation depend
%            on the specific settings of your simulations. For example: you
%            cannot request anything related to ice temperature if your 
%            simulation does not include a thermal model.
%
%   WARNING: DO NOT MODIFY THIS FILE
%            this file has been automatically generated by Synchronize.sh
%            Please read README for more information

%Vector outputs:
END

cat temp |  awk '{print substr($1,1,length($1)-4)}' | awk '/InputsSTART/,/InputsEND/' | grep -v "Inputs" | grep -v "Outputdefinition" >> $ISSM_DIR/src/m/solve/listoutputs.m

cat <<END >> $ISSM_DIR/src/m/solve/listoutputs.m

%Scalar outputs
END
cat ../../classes/FemModel.cpp | awk '/void FemModel::Responsex\(IssmDouble\* responses,int/,/default:/' | grep Enum | sed -e 's/Enum/ /g' | awk {'print $2'} >> $ISSM_DIR/src/m/solve/listoutputs.m
#}}}

#vim file
#Build Enum.vim{{{
#Header
cat <<END > $ISSM_DIR/src/c/shared/Enum/Enum.vim
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" ISSM specific c syntax highlighting
"
"   WARNING: DO NOT MODIFY THIS FILE
"            this file has been automatically generated by Synchronize.sh
"            Please read README for more information
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

"PETSc
syn keyword cType Vec Mat SeqVec SeqMat

"ISSM typedefs
syn keyword cType mxArray ErrorException QuadtreeBox
syn keyword cType IssmDouble IssmPDouble

"ISSM Enums
END
cat temp |  awk '{print "syn keyword cConstant " $1}' >> $ISSM_DIR/src/c/shared/Enum/Enum.vim
cat <<END >> $ISSM_DIR/src/c/shared/Enum/Enum.vim
"ISSM Enums end
END

#Synchronize ISSM objects objects
cat <<END >> $ISSM_DIR/src/c/shared/Enum/Enum.vim

"ISSM objects
END
find $ISSM_DIR/src/c/classes -name "*.cpp" -o -name "*.h" | sed -e "s/\// /g" -e "s/\.cpp//" -e "s/\.h//" | awk '{print  $(NF)}' | sort | uniq | awk '{ printf "syn keyword cType " $1 "\n"}'>> $ISSM_DIR/src/c/shared/Enum/Enum.vim
find $ISSM_DIR/src/c/analyses -name "*Analysis.h" | sed -e "s/\// /g" -e "s/\.cpp//" -e "s/\.h//" | awk '{print  $(NF)}' | sort | uniq | awk '{ printf "syn keyword cType " $1 "\n"}'>> $ISSM_DIR/src/c/shared/Enum/Enum.vim
echo "\"ISSM objects end" >> $ISSM_DIR/src/c/shared/Enum/Enum.vim
#}}}
#Build Enumjl.vim{{{
#Header
cat <<END > $ISSM_DIR/src/c/shared/Enum/Enumjl.vim
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" ISSM specific julia syntax highlighting
"
"   WARNING: DO NOT MODIFY THIS FILE
"            this file has been automatically generated by Synchronize.sh
"            Please read README for more information
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

"ISSM Enums
END
cat temp |  awk '{print "syn keyword juliaConstC " $1}' >> $ISSM_DIR/src/c/shared/Enum/Enumjl.vim
cat <<END >> $ISSM_DIR/src/c/shared/Enum/Enumjl.vim
"ISSM Enums end
END
#}}}

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