#! /bin/sh
# ======================================================================
#  $Id: projectbuilder,v 1.4 2003/11/06 05:56:07 goiwai Exp $
#  $Name: CLDAQ-1-11-00 $
#  $Log: projectbuilder,v $
#  Revision 1.4  2003/11/06 05:56:07  goiwai
#  表示されるコメントがおかしかったので直しました.
#
#  Revision 1.3  2003/10/10 11:49:18  goiwai
#  バグがあったので直しました.サマリも出力するようにしました.
#
#  Revision 1.2  2003/10/10 10:16:26  goiwai
#  ちょとだけ変更しました.
#
#  Revision 1.1  2003/10/06 13:31:01  goiwai
#  ローテクなアプリケーション作成支援ツールです.
#
# ======================================================================
projectname="DAQ"

welcome()
{
    clear
    echo "Welcome: CLDAQ Project Builder"
    echo '$Id: projectbuilder,v 1.4 2003/11/06 05:56:07 goiwai Exp $'
    echo '$Name: CLDAQ-1-11-00 $'
    echo "----"
    return
}

isset()
{
    env | grep "^$1=" | while read e; do
	echo $e
    done
    if [ "$e" != "" ]; then
	return 1
    else
	return 0
    fi
}

guess()
{
    cd ../../
    echo $PWD
}

isbuild()
{
    if [ -f "$CLDAQ_INSTALL/lib/libCLDAQ.a" ]; then
	return 1
    else
	return 0
    fi
}

checkenv()
{
    if [ ! $(isset CLDAQ_INSTALL) ]; then
	echo "Unset CLDAQ_INSTALL"
	d=$(guess)
	echo "ex) setenv CLDAQ_INSTALL $d"
	echo "ex) export CLDAQ_INSTALL=$d"
	echo "ex) source $PWD/cldaq-setup.csh"
	echo "ex) . $PWD/cldaq-setup.sh"
	exit 0
    fi
}

checklib()
{
    isbuild
    RETVAL=$?
    if [ ! $RETVAL ]; then
	echo "Not build CLDAQ library"
	exit 0
    fi
}

setprojectname()
{
    echo -n "Enter project name [$projectname]: "
    read input
    if [ "$input" != "" ]; then
	projectname=$input
    fi

    mkdir $projectname
    #for DEBUG
    #mkdir -p $projectname
    if [ $? -ne 0 ]; then
	exit $?
    fi
}

setexec()
{
    ans="y";
    while [ "$ans" = "y" -o "$ans" = "Y" ]; do
	if [ "$exename" = "" ]; then
	    echo -n "Enter execution file(s) [no default]: "
	else
	    echo -n "Enter execution file(s) [$exename]: "
	fi
	read input
	if [ "$input" = "" ]; then
	    continue
	fi

	if [ "$exename" = "" ]; then
	    exename="$input"
	else
	    already=0
	    for name in $exename; do
		if [ "$input" = "$name" ]; then
		    echo "$input: already exist, not pushed"
		    already=1
		fi
	    done
	    if [ $already -eq 0 ]; then
		exename="$exename $input"
	    fi
	fi
	echo -n "Add more (Y)es/(N)o?: [Y]: "
	read input
	if [ "$input" = "" ]; then
	    continue
	fi
	ans="$input"
    done
}

setlib()
{
    echo -n "Enter library name [$projectname]: "
    read input
    if [ "$input" = "" ]; then
	libname="$projectname"
    else
	libname="$input"
    fi
}

setprefix()
{
    prefix="$libname"
    echo -n "Enter Prefix [$prefix]: "
    read input
    if [ "$input" != "" ]; then
	prefix="$input"
    fi
}

makeclass()
{
    clear
    cd $projectname
    makesysaction
    makerunaction
    makeevtaction
    makecrate
    makereadout
    cd ..
}

makesysaction()
{
    class="${prefix}SystemAction"
    hh="$class.hh"
    cc="$class.cc"
    if [ -f $hh ]; then
	echo "Escape $hh -> $hh.$$"
	mv $hh $hh.$$
    fi
    if [ -f $cc ]; then
	echo "Escape $cc -> $cc.$$"
	mv $cc $cc.$$
    fi
    echo "Making files for ${class} class ..."
    sleep 1
cat > $hh << EOF
// =====================================================================
//  \$Id\$
//  \$Name\$
//  \$Log\$
// =====================================================================
#ifndef __${class}_hh
#define __${class}_hh

#include "TSystemAction.hh"

class TRunManager;

class $class
  : public TSystemAction
{

  public:
    $class();
    ~$class();

  public:
    Tvoid BeginOfSystemAction( TRunManager* manager );
    Tvoid EndOfSystemAction( TRunManager* manager );

};

#endif
EOF

cat > $cc << EOF
// =====================================================================
//  \$Id\$
//  \$Name\$
//  \$Log\$
// =====================================================================
#include "TRunManager.hh"
#include "$class.hh"

$class::$class()
  : TSystemAction()
{;}

$class::~$class()
{;}

Tvoid $class::BeginOfSystemAction( TRunManager* manager )
{
  // NOTE: You should describe to do when boot your system.
  // e.g.) Power on, start the event display.

  return;
}

Tvoid $class::EndOfSystemAction( TRunManager* manager )
{
  // NOTE: You should describe to do when shutodown your system.
  // e.g.) Power off, terminate the event display.

  return;
}
EOF
}

makerunaction()
{
    class="${prefix}RunAction"
    hh="$class.hh"
    cc="$class.cc"
    if [ -f $hh ]; then
	echo "Escape $hh -> $hh.$$"
	mv $hh $hh.$$
    fi
    if [ -f $cc ]; then
	echo "Escape $cc -> $cc.$$"
	mv $cc $cc.$$
    fi
    echo "Making files for ${class} class ..."
    sleep 1

cat > $hh << EOF
// =====================================================================
//  \$Id\$
//  \$Name\$
//  \$Log\$
// =====================================================================
#ifndef __${class}_hh
#define __${class}_hh

#include "TRunAction.hh"

class TRun;

class $class
  : public TRunAction
{

  public:
    $class();
    ~$class();

  public:
    Tvoid BeginOfRunAction( TRun& aRun );
    Tvoid EndOfRunAction( TRun& aRun );

};

#endif
EOF

cat > $cc << EOF
// =====================================================================
//  \$Id\$
//  \$Name\$
//  \$Log\$
// =====================================================================
#include "TRunManager.hh"
#include "TRun.hh"
#include "$class.hh"

$class::$class()
  : TRunAction()
{;}

$class::~$class()
{;}

Tvoid $class::BeginOfRunAction( TRun& aRun )
{
  // NOTE: You should describe to do when start the run.
  // e.g.) open record files, initialize crates, clear event display.

  return;
}

Tvoid $class::EndOfRunAction( TRun& aRun )
{
  // NOTE: You should describe to do when stop the run.
  // e.g.) close record files, generate the run summary.

  return;
}
EOF
}

makeevtaction()
{
    class="${prefix}EventAction"
    hh="$class.hh"
    cc="$class.cc"
    if [ -f $hh ]; then
	echo "Escape $hh -> $hh.$$"
	mv $hh $hh.$$
    fi
    if [ -f $cc ]; then
	echo "Escape $cc -> $cc.$$"
	mv $cc $cc.$$
    fi
    echo "Making files for ${class} class ..."
    sleep 1

cat > $hh << EOF
// =====================================================================
//  \$Id\$
//  \$Name\$
//  \$Log\$
// =====================================================================
#ifndef __${class}_hh
#define __${class}_hh

#include "TEventAction.hh"

class TEvent;
class TReadoutList;

class $class
  : public TEventAction
{

  public:
    $class();
    ~$class();

  public:
    TReadoutList* WaitEvent();
    Tvoid BeginOfEventAction( TEvent& anEvent );
    Tvoid EndOfEventAction( TEvent& anEvent );

};

#endif
EOF

cat > $cc << EOF
// =====================================================================
//  \$Id\$
//  \$Name\$
//  \$Log\$
// =====================================================================
#include "TEventManager.hh"
#include "TEvent.hh"
#include "$class.hh"

$class::$class()
  : TEventAction()
{;}

$class::~$class()
{;}

TReadoutList* $class::WaitEvent()
{
  // NOTE: You should describe to do while waiting trigger.
  // e.g.) You can hack following code in order to return
  // the readout list tagged "EVENT", watch a register of module.
  // 
  // while ( module -> Read() != NOT_EVENT ) {
  //   hack;
  //   hack;
  // }
  // return theReadoutBook -> GetReadoutList( "EVENT" );

  return 0;
}

Tvoid $class::BeginOfEventAction( TEvent& anEvent )
{
  // NOTE: You should describe to do when start the event.

  return;
}

Tvoid $class::EndOfEventAction( TEvent& anEvent )
{
  // NOTE: You should describe to do when stop the event.
  // e.g.) write records, update or clear modules.

  return;
}
EOF
}

makecrate()
{
    class="${prefix}CrateDefinition"
    hh="$class.hh"
    cc="$class.cc"
    if [ -f $hh ]; then
	echo "Escape $hh -> $hh.$$"
	mv $hh $hh.$$
    fi
    if [ -f $cc ]; then
	echo "Escape $cc -> $cc.$$"
	mv $cc $cc.$$
    fi
    echo "Making files for ${class} class ..."
    sleep 1

cat > $hh << EOF
// =====================================================================
//  \$Id\$
//  \$Name\$
//  \$Log\$
// =====================================================================
#ifndef __${class}_hh
#define __${class}_hh

#include "TCrateDefinition.hh"

class TCrate;

class $class
  : public TCrateDefinition
{

  public:
    $class();
    ~$class();

  public:
    TCrate* Define();

};

#endif
EOF

cat > $cc << EOF
// =====================================================================
//  \$Id\$
//  \$Name\$
//  \$Log\$
// =====================================================================
#include "TCrate.hh"
#include "$class.hh"

$class::$class()
  : TCrateDefinition()
{;}

$class::~$class()
{;}

TCrate* $class::Define()
{
  // NOTE: You have to define crate with some modules.
  //   You need not do "new" objects except for a CRATE object.
  //   Modules should be tagged and grouped.

  TCrate* crate = new TCrate();
  // crate -> InstallModule( ... );
  // crate -> InstallModule( ... );
  // crate -> InstallModule( ... );
  return crate;
}
EOF
}

makereadout()
{
    class="${prefix}ReadoutBookDefinition"
    hh="$class.hh"
    cc="$class.cc"
    if [ -f $hh ]; then
	echo "Escape $hh -> $hh.$$"
	mv $hh $hh.$$
    fi
    if [ -f $cc ]; then
	echo "Escape $cc -> $cc.$$"
	mv $cc $cc.$$
    fi
    echo "Making files for ${class} class ..."
    sleep 1

cat > $hh << EOF
// =====================================================================
//  \$Id\$
//  \$Name\$
//  \$Log\$
// =====================================================================
#ifndef __${class}_hh
#define __${class}_hh

#include "TReadoutBookDefinition.hh"

class TReadoutBook;

class $class
  : public TReadoutBookDefinition
{

  public:
    $class();
    ~$class();

  public:
    TReadoutBook* Define();

};

#endif
EOF

cat > $cc << EOF
// =====================================================================
//  \$Id\$
//  \$Name\$
//  \$Log\$
// =====================================================================
#include "TReadoutBook.hh"
#include "$class.hh"

$class::$class()
  : TReadoutBookDefinition()
{;}

$class::~$class()
{;}

TReadoutBook* $class::Define()
{
  // NOTE: You have to define readout book with some lists.
  //   You need not do "new" objects except for a BOOK object.

  TReadoutBook* book = new TReadoutBook();
  // book -> AddReadoutList( list1 );
  // book -> AddReadoutList( list2 );
  // book -> AddReadoutList( list3 );
  return book;
}
EOF
}

makecc()
{
    cd $projectname

    for ccroot in $exename; do
	cc="$ccroot.cc"
	if [ -f $cc ]; then
	    echo "Escape $cc -> $cc.$$"
	    mv $cc $cc.$$
	fi

	sysaction="${prefix}SystemAction"
	runaction="${prefix}RunAction"
	evtaction="${prefix}EventAction"
	crate="${prefix}CrateDefinition"
	readout="${prefix}ReadoutBookDefinition"

	echo "Making execution file for ${ccroot} ..."
	sleep 1

cat > $cc << EOF
// =====================================================================
//  \$Id\$
//  \$Name\$
//  \$Log\$
// =====================================================================
#include "TRunManager.hh"
#include "TArgument.hh"
#include "TTerminalUserInterface.hh"

#include "$sysaction.hh"
#include "$runaction.hh"
#include "$evtaction.hh"
#include "$crate.hh"
#include "$readout.hh"

int main( int argc, char** argv, char** envv )
{
  TArgument arg( argc, argv );

  TRunManager* manager = new TRunManager( new TTerminalUserInterface() );
  manager -> SetSystemAction( new $sysaction() );
  manager -> SetRunAction( new $runaction() );
  manager -> SetEventAction( new $evtaction() );
  manager -> SetCrateDefinition( new $crate() );
  manager -> SetReadoutBookDefinition( new $readout() );
  manager -> SessionStart();

  delete manager;

  return 0;
}
EOF
    done
    cd ..
}

makemakefile()
{
    cd $projectname
    gmk="GNUmakefile"
    if [ -f $gmk ]; then
	echo "Escape $gmk -> $gmk.$$"
	mv $gmk $gmk.$$
    fi

    echo "Making ${gmk} ..."
    sleep 1

cat > $gmk << EOF
# ======================================================================
#  \$Id\$
#  \$Name\$
#  \$Log\$
# ======================================================================
name := $exename
CLDAQ_WORK_DIR = .
CLDAQ_LIB_NAME = $libname
.PHONY: all
all: lib bin
include \$(CLDAQ_INSTALL)/config/binmake.gmk
#LDLIBS += \$(shell root-config --glibs)
#CPPFLAGS += \$(shell root-config --cflags)
#LDLIBS += \$(shell gtk-config --libs)
#CPPFLAGS += \$(shell gtk-config --cflags)
EOF
    cd ..
}

summary()
{
    echo
    echo
    echo "Summary: CLDAQ Project Builder"
    echo "----"
    echo "PROJECT NAME: $projectname"
    echo "PROJECT DIR: $projectname"
    echo "WORKING DIR: $projectname"
    echo "BUILD LIB: lib${libname}.a"
    echo "BUILD EXE: $exename"
    echo
    echo "Now, you can build with following command:"
    echo
    echo "  % cd $projectname"
    echo "  % gmake"
    echo
    echo
    echo
    echo
}

main()
{
    welcome
    checkenv
    checklib
#while
    setprojectname
    setexec
    setlib
    setprefix
#done
    makeclass
    makecc
    makemakefile
    summary
}

main

exit 0
