/*
 *  WIDENTIFY   A companion utility to wIconSetter and wIconify that allows
 *              you to determine the commands necessary to properly identify
 *              a window or screen in the wIconSetter initialization file.
 *
 *  wHandler.c     SetFunction routines for wIdentify.
 *
 *  Copyright 1990 by Davide P. Cervone, all rights reserved.
 *  You may use this code, provided this copyright notice is kept intact.
 */

#include "wIdentify.h"


/*
 *  StripPath()
 *
 *  Start at the end of the string
 *  While there are more characters to look at,
 *    Get the preceding character
 *    If it is '/' or ':' cancel the loop, otherwise back up a character
 *  Clip the length of the name, if necessary
 *  Terminate the Name string
 *  Copy the name portion of the string into the Name buffer
 */

static void StripPath(Name,s,len)
char Name[MAXNAME];
char *s;
short len;
{
   short i = 0;
   char c;

   s += len;
   while (len)
   {
      c = *(s-1);
      if (c == '/' || c == ':') len = 0;
         else len--, s--, i++;
   }
   if (i >= MAXNAME) i = MAXNAME-1;
   Name[i] = 0;
   while (i--) Name[i] = s[i];
}


/*
 *  GetProgramName()
 *
 *  If we have a task to look at,
 *    If the task is a process
 *      If the process has a task number and a CLI structure
 *        Get the CLI structure, and use its current command name and length
 *    If we haven't found the name yet,
 *      Get the name from the task structure, and find its length
 *    Strip the path portion off the name
 *  Otherwise clear the name buffer
 */

void GetProgramName(Name,theTask)
char Name[MAXNAME];
struct Process *theTask;
{
   struct CommandLineInterface *theCLI;
   char *s = NULL;
   short len;

   if (theTask)
   {
      if (theTask->pr_Task.tc_Node.ln_Type == NT_PROCESS)
      {
         if (theTask->pr_TaskNum && theTask->pr_CLI)
         {
            theCLI = (struct CommandLineInterface *)BADDR(theTask->pr_CLI);
            if (theCLI->cli_CommandName)
               s = (char *)(BADDR(theCLI->cli_CommandName)), len = *s++;
         }
      }
      if (s == NULL)
      {
         s = theTask->pr_Task.tc_Node.ln_Name;
         len = strlen(s);
      }
      StripPath(Name,s,len);
   } else {
      Name[0] = 0;
   }
}


/*
 *  HandleWindow()
 *
 *  Get a temporary reply port
 *  If successful,
 *    Get the current task's program name
 *    Save the screen and window pointers and the program name in the message
 *    Set up the reply port for the message, and send the message
 *    Wait for it to be returned, and get the reply
 *    Delete the temporary port
 */

static void HandleWindow(theScreen,theWindow)
struct Screen *theScreen;
struct Window *theWindow;
{
   char Program[MAXNAME];
   struct MsgPort *thePort;
   struct IdMessage theMessage;

   thePort = CreatePort(0,0);
   if (thePort)
   {
      GetProgramName(Program,FindTask(NULL));
      theMessage.Screen = theScreen;
      theMessage.Window = theWindow;
      theMessage.Program = &Program[0];
      theMessage.Message.mn_ReplyPort = thePort;
      theMessage.Message.mn_Length = sizeof(struct IdMessage);
      PutMsg(IdPort,&theMessage);
      WaitPort(thePort); GetMsg(thePort);
      DeletePort(thePort);
   }
}


/*
 *  cOpenWindow()
 *
 *  If we actually got a window, print its information.
 */

void cOpenWindow(theWindow)
struct Window *theWindow;
{
   if (theWindow) HandleWindow(theWindow->WScreen,theWindow);
}


/*
 *  cSetWindowTitles()
 *
 *  If a window is specified and its title is changing,
 *    print its information.
 */

void cSetWindowTitles(theWindow,wTitle,sTitle)
struct Window *theWindow;
UBYTE *wTitle,*sTitle;
{
   if (theWindow && wTitle != (UBYTE *)-ONE)
      HandleWindow(theWindow->WScreen,theWindow);
}


/*
 *  cOpenScreen()
 *
 *  If a screen was openned, print its information as a screen.
 */

void cOpenScreen(theScreen)
struct Screen *theScreen;
{
   if (theScreen) HandleWindow(theScreen,SCREENICON);
}
