/*
 *
 * This is a simple module to allow the 
 * user to compile and execute an applescript
 * which is passed in as a text item.
 *
 *  Sean Hummel <seanh@prognet.com>
 *  1/20/98
 *  RealNetworks
 *
 *  Jay Painter <jpaint@serv.net> <jpaint@gimp.org> <jpaint@real.com>
 *  
 *
 */

#include <Resources.h>
#include <Files.h>
#include <OSA.h>
#include <string.h>
#include "ScriptRunner.h"
#include <script.h>
#include <resources.h>

#ifdef TARGET_API_MAC_CARBON
static
p2cstr(StringPtr p)
{
    unsigned char *c = p;
    int len = c[0];
    strncpy((char *)c+1, (char *)c, len);
    c[len] = 0;
}

static c2pstr(const char *cc)
{
    char *c = (char *)cc; /* Ouch */
    int len = strlen(c);
    
    if ( len > 255 ) len = 255;
    strncpy(c, c+1, len);
    c[0] = len;
}
#endif

OSAError LoadScriptingComponent (ComponentInstance * scriptingComponent);

#if 0
/*
 * store the script as a compile script so that OSA 
 * components may load and execute the script easily
 */
OSAError 
CompileAndSave (const char *text, 
		const char *outfile,
		OSAActiveUPP proc, 
		AEDesc * result)
{

  OSAError err2 = 0;
  AEDesc theScript;
  OSAID compiledScriptID = 0;
  ComponentInstance scriptingComponent;
  FSSpec outfilespec;
  AEDesc theCompiledScript;
  OSAID scriptid = kOSANullScript;
  short saveres = 0;



  /* Initialize theScript here because it is a struct */
  theScript.dataHandle = NULL;
  theCompiledScript.dataHandle = NULL;


  /* open the component manager */
  err2 = LoadScriptingComponent (&scriptingComponent);
  if (err2)
    return err2;		/* <<< Fail quietly?? */


  /* construct the AppleEvent Descriptor to contain the text of script */
  AECreateDesc ('TEXT', text, strlen (text), &theScript);

  err2 = OSACompile (scriptingComponent, 
		     &theScript, 
		     kOSAModeCompileIntoContext, 
		     &scriptid);
  if (err2)
    {
      OSAScriptError (scriptingComponent, kOSAErrorMessage, 'TEXT', result);
      goto CleanUp;
    }


  err2 = OSAStore (scriptingComponent, 
		   scriptid, 
		   typeOSAGenericStorage,
		   kOSAModeCompileIntoContext, 
		   &theCompiledScript);
  if (err2)
    {
      OSAScriptError (scriptingComponent, kOSAErrorMessage, 'TEXT', result);
      goto CleanUp;
    }


  c2pstr (outfile);
  FSMakeFSSpec (0, 0, (StringPtr) outfile, &outfilespec);
  p2cstr ((StringPtr) outfile);

  FSpDelete (&outfilespec);

  FSpCreateResFile (&outfilespec, 'ToyS', 'osas', smRoman);

  saveres = CurResFile ();

  if (saveres)
    {
      short myres = 0;
      myres = FSpOpenResFile (&outfilespec, fsWrPerm);

      UseResFile (myres);
      AddResource (theCompiledScript.dataHandle, 'scpt', 128, "\p");
      CloseResFile (myres);
      UseResFile (saveres);
    }


CleanUp:

  if (theScript.dataHandle)
    AEDisposeDesc (&theScript);

  if (theCompiledScript.dataHandle)
    AEDisposeDesc (&theCompiledScript);

  if (scriptid)
    OSADispose (scriptingComponent, scriptid);

  if (scriptingComponent != 0)
    CloseComponent (scriptingComponent);


  return err2;
}
#endif


OSAError 
CompileAndExecute (const char *text,
		   AEDesc * result,
		   OSAActiveUPP proc)
{
  OSAError err2 = 0;
  AEDesc theScript;
  OSAID compiledScriptID = 0;
  ComponentInstance scriptingComponent;


  /* initialize theScript here because it is a struct */
  theScript.dataHandle = NULL;

  /* Open the component manager */
  err2 = LoadScriptingComponent (&scriptingComponent);
  if (err2)
    return err2;		/* <<< Fail quietly?? */


  /* construct the AppleEvent Descriptor to contain the text of script */
  AECreateDesc ('TEXT', text, strlen (text), &theScript);


  err2 = OSASetActiveProc (scriptingComponent, proc, NULL);
  if (err2)
    goto CleanUp;


  err2 = OSADoScript (scriptingComponent, &theScript, kOSANullScript, 'TEXT', 0, result);
  if (err2)
    {
      OSAScriptError (scriptingComponent, kOSAErrorMessage, 'TEXT', result);
      goto CleanUp;
    }


CleanUp:

  if (theScript.dataHandle)
    AEDisposeDesc (&theScript);

  if (scriptingComponent != 0)
    CloseComponent (scriptingComponent);


  return err2;
}

#if 0
/*
 * This routine reads in a saved script file and executes 
 * the script contained within (from a 'scpt' resource.)
 */
OSAError 
ExecuteScriptFile (const char *theFilePath,
		   OSAActiveUPP proc,
		   AEDesc * result)
{
  OSAError err2;
  short resRefCon;
  AEDesc theScript;
  OSAID compiledScriptID, scriptResultID;
  ComponentInstance scriptingComponent;
  FSSpec theFile;


  c2pstr (theFilePath);
  FSMakeFSSpec (0, 0, (StringPtr) theFilePath, &theFile);
  p2cstr ((StringPtr) theFilePath);


  /* open a connection to the OSA */
  err2 = LoadScriptingComponent (&scriptingComponent);
  if (err2)
    return err2;		/* <<< Fail quietly?? */


  err2 = OSASetActiveProc (scriptingComponent, proc, NULL);
  if (err2)
    goto error;


  /* now, try and read in the script
   * Open the script file and get the resource
   */
  resRefCon = FSpOpenResFile (&theFile, fsRdPerm);
  if (resRefCon == -1)
    return ResError ();

  theScript.dataHandle = Get1IndResource (typeOSAGenericStorage, 1);

  if ((err2 = ResError ()) || (err2 = resNotFound, theScript.dataHandle == NULL))
    {
      CloseResFile (resRefCon);
      return err2;
    }

  theScript.descriptorType = typeOSAGenericStorage;
  DetachResource (theScript.dataHandle);
  CloseResFile (resRefCon);
  err2 = noErr;


  /* give a copy of the script to AppleScript */
  err2 = OSALoad (scriptingComponent, 
		  &theScript, 
		  0L, 
		  &compiledScriptID);
  if (err2)
    goto error;

  AEDisposeDesc (&theScript);
  theScript.dataHandle = NULL;


  err2 = OSAExecute (scriptingComponent, 
		     compiledScriptID,
		     kOSANullScript,
		     0, 
		     &scriptResultID);

  if (compiledScriptID) 
    OSAScriptError (scriptingComponent, kOSAErrorMessage, 'TEXT', result);

  if (err2)
    goto error;

  /* If there was an error, return it. If there was a result, return it. */
  (void) OSADispose (scriptingComponent, compiledScriptID);

  if (err2)
    goto error;
  else
    goto done;

error:
  if (theScript.dataHandle)
    AEDisposeDesc (&theScript);


done:


  return err2;
}
#endif


OSAError 
LoadScriptingComponent (ComponentInstance * scriptingComponent)
{
  OSAError err2;

  /* Open a connection to the Open Scripting Architecture  */
  *scriptingComponent = OpenDefaultComponent (kOSAComponentType,
					      kOSAGenericScriptingComponentSubtype);

  err2 = GetComponentInstanceError (*scriptingComponent);

  return err2;
}
