#! /bin/sh
# ======================================================================
#  $Id: cldaq-build,v 1.5 2004/06/24 15:18:37 goiwai Exp $
#  $Name: CLDAQ-1-14-02 $
#  $Log: cldaq-build,v $
#  Revision 1.5  2004/06/24 15:18:37  goiwai
#  TSystemAction饹ѹˤ碌ơѹ
#
#  Revision 1.4  2004/03/04 14:54:17  goiwai
#  Action饹Ǵؿ̾ѹФ
#
#  Revision 1.3  2004/01/19 22:01:46  goiwai
#  åʤ󤫤äľޤ.
#
#  Revision 1.2  2004/01/19 21:12:55  goiwai
#  ץץåƬCLDAQ__ѹޤ.
#  饹̾ΥץեDaqΤ褦Ƭʸ,ʹߤʸˤʤ
#  褦ˤޤ.
#  ¾ˤäȤХե.
#
#  Revision 1.1  2004/01/06 09:37:00  goiwai
#  projectbuilderǤ.
#
#  Revision 1.5  2004/01/05 11:55:57  goiwai
#  -w,-hץɲ.
#  ŪʤȤͤ getopt ȤۤΤ?
#
#  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"
prog="cldaq-build"

welcome()
{
    clear
#    echo "Welcome: CLDAQ Project Builder"
#    echo '$Id: cldaq-build,v 1.5 2004/06/24 15:18:37 goiwai Exp $'
#    echo '$Name: CLDAQ-1-14-02 $'
    cat <<EOF
CLDAQ - a Class Library for Data AcQuisition
Copyright (C) 2000-2004 Go IWAI <goiwai@users.sourceforge.jp>
  This is free software with ABSOLUTELY NO WARRANTY.
  For details type "$prog --warranty".
----
EOF
}

usage()
{
    cat <<EOF
Usage: $prog [OPTIONS]
Options:
  -h, --help		Show this usage and exit.
  -o, --output		Reserved for next generation.
  -p, --project		Reserved for next generation.
  -q, --quiet		Reserved for next generation.
  -w, --warranty	Show warranty information end exit.
EOF
    exit $1
}

warranty()
{
    clear
cat <<EOF

CLDAQ - a Class Library for Data AcQuisition
Copyright (C) 2000-2004 Go IWAI <goiwai@users.sourceforge.jp>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License , or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program. If not, write to

       The Free Software Foundation, Inc.
       59 Temple Place, Suite 330
       Boston, MA 02111, USA.

EOF
    exit $1
}

setargs()
{
    while test $# -gt 0; do
	case "$1" in
	    -*=*)
		optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'`
		;;
	    *)
		optarg=
		;;
	esac

	case $1 in
	    --h*|-h)
		usage 1 1>&2
		;;
	    --o*|-o)
		;;
	    --p*|-p)
		;;
	    --q*|-q)
		;;
	    --w*|-w)
		warranty 1 1>&2
		;;
	    *)
		usage 1 1>&2
		;;
	esac
	shift
    done
}

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()
{
    liba="$CLDAQ_INSTALL/lib/libCLDAQ.a"
    libso="$CLDAQ_INSTALL/lib/libCLDAQ.so"
    if test -f $liba || test -f $libso; 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 name(s) [no default]: "
	else
	    echo -n "Enter execution name(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()
{
    # ƬΤʸǰʹߤϾʸ(2004-01-19)
    pre=$(echo $libname | cut -c1 | tr a-z A-Z)
    post=$(echo $libname | cut -c2- | tr A-Z a-z)
    prefix="$pre$post"

    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"
    # ʸΤߤΥ饹̾Ѱ(2004-01-19)
    CLASS=$(echo $class | tr a-z A-Z)
    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 CLDAQ__${CLASS}_HH
#define CLDAQ__${CLASS}_HH

#include "TSystemAction.hh"

class TRunManager;

class $class
  : public TSystemAction
{

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

  public:
    Tvoid Boot( TRunManager* manager );
    Tvoid Shutdown( TRunManager* manager );

  public:
    Tvoid CatchStandardOut( Tstring message );
    Tvoid CatchStandardError( Tstring message );
    Tvoid CatchLog( Tstring message, Tint level );

};

#endif
EOF

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

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

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

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

  return;
}

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

  return;
}

Tvoid $class::CatchStandardOut( Tstring message )
{
  // NOTE: You should describe to do when your system wrote it down
  // standard output on your terminal.
  // e.g.) std::cout << message << std::flush;
  std::cout << message << std::flush;

  return;
}

Tvoid $class::CatchStandardError( Tstring message )
{
  // NOTE: You should describe to do when your system wrote it down
  // standard error on your terminal.
  // e.g.) std::cerr << message << std::flush;
  std::cerr << message << std::flush;

  return;
}

Tvoid $class::CatchLog( Tstring message, Tint level )
{
  // NOTE: You should describe to do when send message to your system logger.
  // I provide you very useful tool TSystemLogging, see header file.
  // e.g.) std::clog << message << std::flush;
  std::clog << message << std::flush;

  return;
}
EOF
}

makerunaction()
{
    class="${prefix}RunAction"
    # ʸΤߤΥ饹̾Ѱ(2004-01-19)
    CLASS=$(echo $class | tr a-z A-Z)
    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 CLDAQ__${CLASS}_HH
#define CLDAQ__${CLASS}_HH

#include "TRunAction.hh"

class TRun;

class $class
  : public TRunAction
{

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

  public:
    Tvoid Start( TRun& aRun );
    Tvoid Stop( TRun& aRun );
    Tvoid Suspend( TRun& aRun );
    Tvoid Resume( 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::Start( 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::Stop( TRun& aRun )
{
  // NOTE: You should describe to do when stop the run.
  // e.g.) close record files, generate the run summary.

  return;
}

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

  return;
}

Tvoid $class::Resume( 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"
    # ʸΤߤΥ饹̾Ѱ(2004-01-19)
    CLASS=$(echo $class | tr a-z A-Z)
    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 CLDAQ__${CLASS}_HH
#define CLDAQ__${CLASS}_HH

#include "TEventAction.hh"

class TEvent;
class TReadoutList;

class $class
  : public TEventAction
{

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

  public:
    TReadoutList* WaitTrigger();
    Tvoid AtFirst( TEvent& anEvent );
    Tvoid AtLast( 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::WaitTrigger()
{
  // 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::AtFirst( TEvent& anEvent )
{
  // NOTE: You should describe to do when start the event.

  return;
}

Tvoid $class::AtLast( 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"
    # ʸΤߤΥ饹̾Ѱ(2004-01-19)
    CLASS=$(echo $class | tr a-z A-Z)
    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 CLDAQ__${CLASS}_HH
#define CLDAQ__${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"
    # ʸΤߤΥ饹̾Ѱ(2004-01-19)
    CLASS=$(echo $class | tr a-z A-Z)
    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 CLDAQ__${CLASS}_HH
#define CLDAQ__${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 ${cc} 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 "Summary: CLDAQ Project Builder ($prog)"
    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
}

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

main $*

exit 0
