#!/bin/sh

function rep () {
    local a=$1
    local al="`echo "$a" | tolower`" 
    local au="`echo "$a" | toupper`"
    local b=$2
    local bl="`echo "$b" | tolower`" 
    local bu="`echo "$b" | toupper`"
    sed "s/$al/$bl/g" | sed "s/$a/$b/g" | sed "s/$au/$bu/g"
}    

function begns () {
    local BEGSYS="__BEGIN_SYS"
    local BEGINT="__BEGIN_INT"
    local BEGIMP="__BEGIN_IMP"

    echo -e $BEGSYS
    case "$type" in
	interface) echo -e $BEGINT;;
	abstraction) echo -e $BEGIMP;;
	aspect) ;;
	mediator) ;;
	*) return 1;;
    esac
}    

function endns () {
    local ENDSYS="__END_SYS"
    local ENDINT="__END_INT"
    local ENDIMP="__END_IMP"

    case "$type" in
	interface) echo -e $BEGINT;;
	abstraction) echo -e $ENDIMP;;
	aspect) ;;
	mediator) ;;
	*) return 1;;
    esac
    echo -e $ENDSYS
}    

function newii () {
    local PRO="#ifndef __file_h\n#define __file_h\n"
    local EPI="#endif\n"
    local INC="#include <file.h>\n"
    local MEMINC="#ifdef __MEMBER_H\n#include __MEMBER_H\n#endif\n"
    local FAM="class Family
{
public:
    Family();
    Family(const Id & id);
    Family(const Family & family);
    ~Family();

    const Id & id();
    bool valid();

    // methods
};\n"
    local MEM="class Member
{
public:
    Member();
    Member(const Id & id);
    Member(const Member & member);
    ~Member();

    const Id & id();
    bool valid();

    // methods
};\n"

    if (( $# < 2 )); then
	return 1
    fi
    
    local type="interface"
    local family=$2
    shift 2
    local members="$*"
    
    echo -e "`echo "$PRO" | rep File "$family"`"
    echo -e "`echo "$INC" | rep File Config`" 
    echo -e "`begns`\n" 
    echo -e "`echo "$FAM" | rep Family "$family"`" 
    for member in $members; do
	echo -e "`echo "$MEM" | rep Member "$member"`" 
    done
    echo -e "`endns`\n" 
    for member in $members; do
	echo -e "`echo "$MEMINC" | rep Member "$member"`" 
    done
    echo -e "$EPI" 
    
    return 0
}

function newco () {
    local PRO="#ifndef __file_h\n#define __file_h\n"
    local EPI="#endif\n"
    local INC="#include <system/config.h>\n#include <system/info.h>\n"

    local COM="class Common
{
protected:
    Common() {}

public:
    // methods

protected:
    // data
};\n"

    if (( $# != 2 )); then
	return 1
    fi

    local type=$1
    local common=$2"_Common"

    echo -e "`echo "$PRO" | rep File "$common"`"
    echo -e "$INC"
    echo -e "`begns`\n"
    echo -e "`echo "$COM" | rep Common "$common"`"
    echo -e "`endns`\n"
    echo -e "$EPI"

    return 0
}

function newme () {
    local PRO="#ifndef __file_h\n#define __file_h\n"
    local EPI="#endif\n"
    local INC="#include \"common.h\"\n"
    local MEM="class Member: private Family_Common
{
public:
    Member();
    ~Member();

    // methods

    static int init(System_Info *si);

protected:
    // data
};\n"

    if (( $# != 3 )); then
	return 1
    fi

    local type=$1
    local family=$2
    local member=$3

    echo -e "`echo "$PRO" | rep File "$member"`"
    echo -e "$INC"
    echo -e "`begns`\n"
    echo -e "`echo "$MEM" | rep Family "$family" | rep Member "$member"`"
    echo -e "`endns`\n"
    echo -e "$EPI"

    return 0
}

function newmf () {
    local PRO="# EPOS Family Makefile\n#\n# Author: Guto\n\ninclude \$(EPOS)/makedefs\n"
    local ALL="all:\t\t\$(LIBSYS) \$(LIBDATA) \$(LIBINIT)\n"
    local SYS="\$(LIBSYS):\tmembers\n\t\t\$(AR) \$(ARFLAGS) \$@ \$^\n"
    local DAT="\$(LIBDATA):\tmembers\n\t\t\$(AR) \$(ARFLAGS) \$@ \$^\n"
    local INI="\$(LIBINIT):\tmembers\n\t\t\$(AR) \$(ARFLAGS) \$@ \$^\n"
    local TST="test:\t\tmembers\n"
    local PRN="print:\n\t\t\$(PRINT) \$(INCLUDE)/family.h"
    local PRN2="\t\t\$(PRINT) \$(INCLUDE)/system/types/family/member.h member.cc"
    local CLN="clean:\n\t\t\$(CLEAN) *.o *_test\n"

    if (( $# < 2 )); then
	return 1
    fi

    local type=$1
    local family=$2
    shift 2
    local members="$*"

    echo -e "`echo "$PRO" | rep Family "$family"`"
    echo -e "`echo "$ALL" | rep members "$members"`"
    for member in $members; do
	local sys="$sys$member"".o "
	local dat="$dat$member""_data.o "
	local ini="$ini$member""_init.o "
	local tst="$tst$member""_test "
    done    
    echo -e "`echo "$SYS" | rep members "$sys"`" 
    echo -e "`echo "$DAT" | rep members "$dat"`" 
    echo -e "`echo "$INI" | rep members "$ini"`" 
    echo -e "`echo "$TST" | rep members "$tst"`" 
    echo -e "`echo "$PRN" | rep family "$family"`" 
    for member in $members; do
	echo -e "`echo "$PRN2" | rep type "$type" | rep family "$family"\
	    |  rep member "$member"`" 
    done    
    echo 
    echo -e "$CLN" 

    return 0
}

function newimp () {
    local INC="#include <system/types/family/member.h>\n"
    local MEM="Member::Member()
{
    dbtrc << \"Member()\n\";
}

Member::~Member()
{
    dbtrc << \"~Member()\n\";
}

// void Member::method(void)
// {
//     dbtrc << \"Member::method()\n\";
// }"

    if (( $# != 3 )); then
	return 1
    fi

    local type=$1
    local family=$2
    local member=$3

    echo -e "`echo "$INC" | rep Type "$type" | rep Family "$family"\
	    | rep Member "$member"`"
    echo -e "`begns`\n"
    echo "`echo "$MEM" | rep Member "$member"`"
    echo -e "\n`endns`\n"
    echo -e "$EPI"
    
    return 0
}

function newdat () {
    local INC="#include <system/types/family/member.h>\n"

    local MEM="// void Member::data;\n"
    
    if (( $# != 3 )); then
	echo "usage: `basename $0` <type> <family> <member>"
	return 1
    fi
    
    local type=$1
    local family=$2
    local member=$3
    
    echo -e "`echo "$INC" | rep Type "$type" | rep Family "$family"\
	    | rep Member "$member"`"
    echo -e "`begns`\n"
    echo -e "`echo "$MEM" | rep Member "$member"`"
    echo -e "`endns`\n"
    echo -e "$EPI"
    
    return 0
}

function newini () {
    local INC="#include <system/types/family/member.h>\n"
    local MEM="int Member::init(System_Info * si)
{
    return 0;
}\n"

    if (( $# != 3 )); then
	return 1
    fi

    local type=$1
    local family=$2
    local member=$3

    echo -e "`echo "$INC" | rep Type "$type" | rep Family "$family"\
	    | rep Member "$member"`"
    echo -e "`begns`\n"
    echo -e "`echo "$MEM" | rep Member "$member"`"
    echo -e "`endns`\n"
    echo -e "$EPI"
    
    return 0
}

function invoke () {
    local out="`echo "$1" | tolower`"
    local cmd=$2
    shift 2
    local par=$*

#    echo -n "Creating $out ... "

    if [ -f "$out" ]; then
	echo "file exists, skipping!"
	return 1
    fi
    
    echo -e "\n" $cmd $par $out

    if (( $? )); then
	echo "`basename $cmd` failed!"
	return 1
    fi
 
#    echo "done!"
    return 0
}
