// $Id: debugCmd.cpp,v 1.4 2003/03/16 14:51:02 fukasawa Exp $

//=============================================================================
/**
 *  @file    debugCmd.cpp
 *
 *  @author  Fukasawa Mitsuo
 *
 *
 *    Copyright (C) 2002 BEE Co.,Ltd. All rights reserved.
 *
 * 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-1307, USA.
 */
//=============================================================================

#define BEE_BUILD_DLL

#ifdef _MSC_VER
#pragma warning(disable: 4786)  // too long identifier
#endif

#include "JGEquipment.h"
#include "JGTimeModule.h"
#include "JGCommDevice.h"
#include "tclbee.h"

#ifdef _MSC_VER
#include <windows.h>
#endif

// function prototype


/*
 *----------------------------------------------------------------------
 *
 * Gem_debugCmd --
 *
 *      This procedure is invoked to process the "gem::debug"
 *      command. See the user documentation for details on what it does.
 *
 * Results:
 *      A standard Tcl result.
 *
 * Side effects:
 *      See the user documentation.
 *
 *----------------------------------------------------------------------
 */

    /* ARGSUSED */
int
Gem_debugCmd(ClientData arg, Tcl_Interp * interp, int objc,
             Tcl_Obj *CONST objv[])
{
    static char *gemcmds[] = {
        "hexdump",
        "clock",
        NULL
    };
    /*
     * All commands enums below ending in X are compatibility
     */
    enum gemcmds {
        GEMCMD_HEXDUMP,
        GEMCMD_CLOCK,
    };

    Tcl_Obj * res;
    int     cmdindex, result;
    char *  boolStr;
    char *  subStr;
    char *  clockStr;
    string  buf;
    JGEquipment * equipment = (JGEquipment *)arg;
    int  dt;

    Tcl_ResetResult(interp);
    result = TCL_OK;

    JGEquipment * jyugem = (JGEquipment *)arg;
    JGTimeModule * clock = (JGTimeModule *)jyugem->findManager("CLOCK");

    /*
     * Get the command name index from the object based on the cmds
     * defined above.
     */
    if (Tcl_GetIndexFromObj(interp,
        objv[1], (const char **)gemcmds, "command", TCL_EXACT, &cmdindex) != TCL_OK)
        return TCL_ERROR;

    res = NULL;
    switch ((enum gemcmds)cmdindex) {
    case GEMCMD_HEXDUMP:
        if (objc != 3)
        {
            Tcl_WrongNumArgs(interp, 2, objv, "hexdump ?enable ?");
            return TCL_ERROR;
        }

        // Convert string to value
        boolStr = Tcl_GetStringFromObj(objv[2], NULL);
        equipment->device()->hexDump((EQUALSTR(boolStr, "true")) ? true : false);
        break;

    case GEMCMD_CLOCK:
        if (objc == 2)
        {   // Print clock info.
            clock->getDateAndTime(buf);
            Tcl_AppendResult(interp, buf.c_str(), " (", NULL);
            clock->getSystemClock(buf);
            Tcl_AppendResult(interp, buf.c_str(), " + ", NULL);
            ACE_Time_Value dtv = JGTimeModule::instance()->delta();
            char tmbuf[32];
            sprintf(tmbuf, "%ld", dtv.sec());
            Tcl_AppendResult(interp, tmbuf, ")", NULL);
        }
        else if (objc == 4)
        {
            subStr = Tcl_GetStringFromObj(objv[2], NULL);
            if (EQUALSTR(subStr, "set"))
            {
                clockStr = Tcl_GetStringFromObj(objv[3], NULL);
                int len = strlen(clockStr);
                if (len == 12 || len == 16)
                {
                    for (int i = 0; i < len; i++)
                    {
                        if (! isdigit(*(clockStr + i)))
                        {
                            Tcl_AppendResult(interp, "Illegal time format: ",
                                                     clockStr, NULL);
                            return TCL_ERROR;
                        }
                    }
                    if (strtol(clockStr, NULL, 10) == 0)
                    {
                        Tcl_AppendResult(interp, "Illegal time format: ",
                                                 clockStr, NULL);
                        return TCL_ERROR;
                    }
                    clock->setDateAndTime(clockStr);
                }
                else
                {
                    return TCL_ERROR;
                }
            }
            else if (EQUALSTR(subStr, "delta"))
            {
                result = Tcl_GetIntFromObj(interp, objv[3], &dt);
                if (result == TCL_OK)
                {
                    BS2TimeValue dtv = dt;
                    clock->delta(dtv);
                }
                else
                {
                    Tcl_AppendResult(interp, "Illegal timeval: ",
                                     Tcl_GetStringFromObj(objv[3], NULL),
                                     NULL);
                }
            }
            else
            {
                Tcl_AppendResult(interp, "Illegal sub-command: ", subStr, NULL);
                return TCL_ERROR;
            }
        }
        else
        {
            Tcl_WrongNumArgs(interp, 2, objv, "clock ?args ?");
            return TCL_ERROR;
        }
        break;

    }

    /*
     * For each different arg call different function to create
     * new commands (or if version, get/return it).
     */
    if (result == TCL_OK && res != NULL)
        Tcl_SetObjResult(interp, res);

    return TCL_OK;
}

