// This code implementation is the intellectual property of
// the GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4oCommon.icc,v 1.2.8.1 1999/12/07 20:49:06 gunter Exp $
// GEANT4 tag $Name: geant4-01-00 $
//
/*
   Included by G4o.cc.
*/

/***************************************************************************/
void SetTypes (
)
/***************************************************************************/
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
{
  OType otype;
/*.........................................................................*/
  if(OTypeGetIdentifier("G4")!=NULL) return; /*Done*/

  otype                          = OTypeCreate ("G4");
  OTypeSetDoMethodFunction       (otype,DoMethod);
  OTypeAddNewClassMethodProperty (otype,"getCommandGuidance" ,OPropertyString,NULL);
  OTypeAddNewClassMethodProperty (otype,"askListOfCommands"  ,OPropertyString,NULL);
  OTypeAddNewClassMethodProperty (otype,"createCommandPanel" ,OPropertyVoid,NULL);

}
/***************************************************************************/
int Execute_G4 (
 int    a_argn
,char** a_args
,OProcess  a_process
)
/***************************************************************************/
/*
  osh> G4 <string:command> <string:param 1> ...
*/
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
{
  int   count;
  char* string = NULL;
/*.........................................................................*/
  if(a_argn<=1) 
    {
      CWarnF ("At least one argument expected in:\n%s\n",OProcessGetCommand(a_process));
      return EXIT_FAILURE;
    }
  for(count=1;count<a_argn;count++)
    {
      CStringConcatenate (&string,a_args[count]);
      CStringConcatenate (&string," ");
    }
  ExecuteScript    (string);
  CStringDelete    (string);
  return           EXIT_SUCCESS;
}
/***************************************************************************/
void ExecuteScript (
 char* a_string
)
/***************************************************************************/
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
{
  G4UImanager* UI;
  int          linen = 0;
  char**       lines = NULL;
/*.........................................................................*/
  UI    = G4UImanager::GetUIpointer();
  if(UI==NULL) return;
  lines  = CTextCreateFromString (a_string,&linen);
  if( (linen!=0) && (lines!=NULL) )
    {
      int count;
      for(count=0;count<linen;count++)
	{
	  CStringTrim(lines[count]);
	  if( (lines[count]==NULL) || (lines[count][0]=='\0') || (lines[count][0]=='#') ) continue;
	  UI->ApplyCommand(lines[count]);
	}
    }
  CTextDelete (linen,lines);
}
/***************************************************************************/
int DoMethod (
 OIdentifier This
,char*  a_name
,void*  a_user
,int    a_argn
,char** a_args
,void*  a_addr 
,int*   a_number
)
/***************************************************************************/
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
{
/*.........................................................................*/
  if(a_number!=NULL) *a_number = 0;
  if(a_name==NULL)  return 0;

  if(This==NULL)
    {
      if(strcmp(a_name,"getCommandGuidance")==0)  
	{
	  G4UIcommand* command;
	  char*        string = NULL;
	  int          count,linen,paramn;
	  if(a_argn!=1) 
	    {
	      CWarnF  ("One arguments expected for %s property.\n",a_name);
	      return 0;
	    }
	  command = GetCommandIdentifier(a_args[0]);
	  if(command==NULL)
	    {
	      CWarnF  ("Unknown G4 command :\n%s\n",a_args[0]);
	      return 0;
	    }
	  linen = command->GetGuidanceEntries();
	  for(count=0;count<linen;count++)
	    { 
	      CStringConcatenate (&string,(char*)command->GetGuidanceLine(count).data());
	      CStringConcatenate (&string,"\n");
	    }
	  paramn = command->GetParameterEntries();
	  for(count=0;count<paramn;count++)
	    { 
	      char* info;
	      char* line;
	      G4UIparameter* parameter = (G4UIparameter*)command->GetParameter(count);

	      info               = (char*)parameter->GetParameterName().data();
	      line               = CStringCreateF(12+strlen(info)+1,"Parameter : %s\n",info);
	      CStringConcatenate (&string,line);
              CStringDelete      (line);

	      if( ! parameter->GetParameterGuidance().isNull() )
		{
		  CStringConcatenate (&string,(char*)parameter->GetParameterGuidance().data());
		  CStringConcatenate (&string,"\n");
		}
	      
	      line               = CStringCreateF(19+1+1," Parameter type  : %c\n",parameter->GetParameterType());
	      CStringConcatenate (&string,line);
              CStringDelete      (line);

	      if(parameter->IsOmittable()==True)
                line = CStringDuplicate(" Omittable       : true\n");
	      else
                line = CStringDuplicate(" Omittable       : false\n");
	      CStringConcatenate (&string,line);
              CStringDelete      (line);

	      if( ! parameter->GetDefaultValue().isNull() )
		{
		  info               = (char*)parameter->GetDefaultValue().data();
		  line               = CStringCreateF(19+strlen(info)+1," Default value   : %s\n",info);
		  CStringConcatenate (&string,line);
		  CStringDelete      (line);
		}

	      if( ! parameter->GetParameterRange().isNull() )
		{
		  info               = (char*)parameter->GetParameterRange().data();
		  line               = CStringCreateF(19+strlen(info)+1," Parameter range : %s\n",info);
		  CStringConcatenate (&string,line);
		  CStringDelete      (line);
		}
	    }
	  *((char**)a_addr) = string;
	  return              FREE_BLOCK;
	}
      else if(strcmp(a_name,"askListOfCommands")==0)  
	{
	  G4UIcommandTree*    treeTop;
	  char*               string = NULL;
	  G4UImanager*        UI;
	  int                 linen = 0;
	  char**              lines = NULL;
	  UI                  = G4UImanager::GetUIpointer();
	  if(UI==NULL)        return 0;
	  treeTop             = UI->GetTree();
	  if(treeTop==NULL)   return 0;
	  if(a_argn==1)       treeTop = treeTop->GetTree(a_args[0]);
	  GetCommands         (treeTop,&linen,&lines);
	  string              = CTextConvertToString (linen,lines,"\n");
	  CTextDelete         (linen,lines);
	  *((char**)a_addr) = string;
	  return              FREE_BLOCK;
	}
      else if(strcmp(a_name,"createCommandPanel")==0)  
	{
	  if(a_argn!=2) 
	    {
	      CWarnF  ("Two arguments expected for %s property.\n",a_name);
	      return 0;
	    }
	  return ProduceODB(GetCommandIdentifier(a_args[0]),a_args[1]);
	}
      else 
	{
	  CInfoF ("G4_DoMethod: %s is not a class routine property.\n",a_name);
	  return 0;
	}
    }

  CInfoF ("G4_DoMethod: %s is not a routine property.\n",a_name);

  a_user = NULL;
  a_argn = 0;
  a_args = NULL;
  a_addr = NULL;
  return 0;
}
/***************************************************************************/
void GetCommands (
 G4UIcommandTree* a_tree
,int* a_linen
,char*** a_lines
)
/***************************************************************************/
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
{
/*.........................................................................*/
  if(a_tree==NULL) return;

  int  n_commandEntry = a_tree->GetCommandEntry();
  for( int i_thCommand = 1; i_thCommand <= n_commandEntry; i_thCommand++ )
    {
      G4UIcommand* command = a_tree->GetCommand(i_thCommand);
      CTextAddLine (a_linen,a_lines,(char*)command->GetCommandPath().data());
    }

  int  n_treeEntry = a_tree->GetTreeEntry();
  for( int i_thTree = 1; i_thTree <= n_treeEntry; i_thTree++ )
    {
      GetCommands (a_tree->GetTree(i_thTree),a_linen,a_lines);
    }

}
/***************************************************************************/
G4UIcommand* GetCommandIdentifier (
 char* a_name
)
/***************************************************************************/
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
{
  G4UImanager*       UI;
  G4UIcommandTree*   treeTop;
/*.........................................................................*/
  if(a_name==NULL)   return NULL;
  UI                 = G4UImanager::GetUIpointer();
  if(UI==NULL)       return NULL;
  treeTop            = UI->GetTree();
  if(treeTop==NULL)  return NULL;
  return             treeTop->FindPath(a_name);
}
/***************************************************************************/
int ProduceODB (
 G4UIcommand* a_command
,char* a_name
)
/***************************************************************************/
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
{
  FILE* file;
  int   paramn,parami;
  char* top = NULL;
/*.........................................................................*/
  if(a_command==NULL) return 0;

  paramn = a_command->GetParameterEntries();

  file = CFileOpenForWriting (a_name);
  if(file==NULL) return 0;

  fprintf (file,"\
!----------------------------\n\
begin OInterface\n\
 prefix = G4Params_\n\
end\n\
!----------------------------\n\
begin OWidget\n\
 name = G4Params_palette\n\
 type = XmFormDialog\n\
 children = G4Params_command\
");
  for(parami=0;parami<paramn;parami++)
    { 
      fprintf (file," G4Params_label_%d G4Params_text_%d",parami,parami);
    }
  fprintf (file," G4Params_ok G4Params_apply G4Params_cancel\n\
 autoUnmanage = False\n\
 dialogTitle = G4 parameters\n\
end\n\
!----------------------------\n\
begin OWidget\n\
 name = G4Params_command\n\
 type = XmPushButton\n\
 labelString = %s\n\
 background = black\n\
 foreground = white\n\
 leftAttachment = attach_form\n\
 rightAttachment = attach_form\n\
 topAttachment = attach_form\n\
 activateCallback = osh>\\\n\
   command=`getWidgetResource G4Params_command labelString`\\\n\
   echo `do G4 getCommandGuidance $command`\n\
end\n\
",a_command->GetCommandPath().data());

  for(parami=0;parami<paramn;parami++)
    { 
      G4UIparameter* parameter = (G4UIparameter*)a_command->GetParameter(parami);
      fprintf (file,"\
!----------------------------\n\
begin OWidget\n\
 name = G4Params_label_%d\n\
 type = XmLabel\n\
 labelString = %s\n\
 createCallback = osh> setWidgetResource `thisWidget` height `getWidgetResource G4Params_text_%d height`\n\
 leftAttachment = attach_form\n\
",parami,parameter->GetParameterName().data(),parami);
      if(parami==0)
	{
      fprintf (file,"\
 topAttachment = attach_widget\n\
 topWidget = G4Params_command\n\
");
	}
      else
	{
      fprintf (file,"\
 topAttachment = attach_widget\n\
 topWidget = G4Params_text_%d\n\
",parami-1);
	}
      fprintf (file,"\
end\n\
!----------------------------\n\
begin OWidget\n\
 name = G4Params_text_%d\n\
 type = XmText\n\
 leftAttachment = attach_widget\n\
 leftWidget = G4Params_label_%d\n\
 rightAttachment = attach_form\n\
",parami,parami);
      if(parami==0)
	{
      fprintf (file,"\
 topAttachment = attach_widget\n\
 topWidget = G4Params_command\n\
");
	}
      else
	{
      fprintf (file,"\
 topAttachment = attach_widget\n\
 topWidget = G4Params_text_%d\n\
",parami-1);
	}

      if( ! parameter->GetDefaultValue().isNull() )
	{
      fprintf (file,"\
 value = %s\n\
",parameter->GetDefaultValue().data());
	}

      fprintf (file,"\
end\n\
");

    }

  if(paramn>=1)
    {
      top = CStringCreateF(14+32,"G4Params_text_%d",paramn-1);
    }
  else
    {
      top = CStringDuplicate("G4Params_command");
    }

  fprintf (file,"\
!----------------------------\n\
begin OWidget\n\
 name = G4Params_ok\n\
 type = XmPushButton\n\
 labelString = Ok\n\
 activateCallback = osh>\\\n\
   command=`getWidgetResource G4Params_command labelString`\\\n\
");
  for(parami=0;parami<paramn;parami++)
    { 
      fprintf (file,"\
   param_%d=`getWidgetResource G4Params_text_%d value`\\\n\
",parami,parami);
    }
  fprintf (file,"\
   G4 $command");
  for(parami=0;parami<paramn;parami++)
    { 
      fprintf (file," $param_%d",parami);
    }
  fprintf (file,"\\\n\
   unmanageWidget `thisWidgetParent`\n\
 bottomAttachment = attach_form\n\
 leftAttachment = attach_form\n\
 topAttachment = attach_widget\n\
 topWidget = %s\n\
end\n\
!----------------------------\n\
begin OWidget\n\
 name = G4Params_apply\n\
 type = XmPushButton\n\
 labelString = Apply\n\
 activateCallback = osh>\\\n\
   command=`getWidgetResource G4Params_command labelString`\\\n\
",top);
  for(parami=0;parami<paramn;parami++)
    { 
      fprintf (file,"\
   param_%d=`getWidgetResource G4Params_text_%d value`\\\n\
",parami,parami);
    }
  fprintf (file,"\
   G4 $command");
  for(parami=0;parami<paramn;parami++)
    { 
      fprintf (file," $param_%d",parami);
    }
  fprintf (file,"\n\
 bottomAttachment = attach_form\n\
 leftAttachment = attach_widget\n\
 leftWidget = G4Params_ok\n\
 topAttachment = attach_widget\n\
 topWidget = %s\n\
end\n\
!----------------------------\n\
begin OWidget\n\
 name = G4Params_cancel\n\
 type = XmPushButton\n\
 labelString = Cancel\n\
 activateCallback = osh> unmanageWidget `thisWidgetParent`\n\
 bottomAttachment = attach_form\n\
 leftAttachment = attach_widget\n\
 leftWidget = G4Params_apply\n\
 rightAttachment = attach_form\n\
 topAttachment = attach_widget\n\
 topWidget = %s\n\
end\n\
",top,top);

  CStringDelete (top);

  fclose(file);

  return 1;
}
