/* Copyright 1997 Acorn Computers Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/***************************************************/
/* File   : PlugIn.h                               */
/*                                                 */
/* Purpose: Supporting the generic RISC OS browser */
/*          Plug-In interface.                     */
/*                                                 */
/* Author : A.D.Hodgkinson                         */
/*                                                 */
/* History: 28-Sep-97: Created.                    */
/***************************************************/

/* Structures - queue of ready-to-launch Plug-Ins */

typedef struct plugin_queue
{
  struct plugin_queue * next;

  browser_data        * browser;
  HStream             * token;
  BBox                  position;
}
plugin_queue;

/* For the Plug-In streaming protocol, where quite a lot of */
/* information needs to be retained for a long time.        */

typedef struct plugin_stream
{
  unsigned int   browser_instance_handle; /* The browser owning the Object   */
  HStream      * token;                   /* HStream representing the Object */

  unsigned int   plugin_instance_handle;
  unsigned int   plugin_stream_handle;
  unsigned int   plugin_task_handle;      /* ...So we know who to talk to later */

  unsigned int   stream_flags;            /* From flags word of Message_PlugIn_StreamNew */

  string_value   url;                     /* These will be allocated in RMA, */
  string_value   mime;                    /* so great care must be taken to  */
  string_value   target;                  /* ensure they're always freed up. */
  string_value   filename;

  int            eos;
  int            last_modified;
  int            notify;                  /* From a Message_PlugIn_URLAccess */

  unsigned int   active            :1;    /* 1 if the stream is open, else 0 (e.g. waiting for message protocol to complete) */
  unsigned int   will_close_itself :1;    /* 1 if the stream will close itself, else close it (e.g. at window close time)    */
  unsigned int   abandoned         :1;    /* 1 if the stream fetch was closed forcibly (abandoned), else 0.                  */
}
plugin_stream;

/* Message definitions - needs string_value to be known, */
/* found in MiscDefs.h.                                  */
/*                                                       */
/* These definitions are uncommented, as it is assumed   */
/* that the reader is completely familiar with the       */
/* Plug-In specification already.                        */

#define Message_PlugIn_Open                        0x4d540

#define MPlugIn_Open_OpenAsHelperNotPlugIn         (1<<0);

typedef struct MPlugIn_Open
{
  unsigned int flags;
  unsigned int reserved;

  int          browser_instance_handle;
  int          parent_window_handle;

  BBox         parent_area;

  int          file_type;
  string_value file_name;
}
MPlugIn_Open;

/* Plug-In opening */

#define Message_PlugIn_Opening                     0x4d541

#define MPlugIn_Opening_CanAcceptInputFocus        (1u<<0)
#define MPlugIn_Opening_WantsCodeResourceFetched   (1u<<1)
#define MPlugIn_Opening_WantsDataResourceFetched   (1u<<2)
#define MPlugIn_Opening_WillDeleteParamsItself     (1u<<3)
#define MPlugIn_Opening_PlugInHasMoreWorkToDo      (1u<<4)
#define MPlugIn_Opening_ActionBeyondStop           (1u<<5)
#define MPlugIn_Opening_OpenedAsHelperNotPlugIn    (1u<<6)

typedef struct MPlugIn_Opening
{
  unsigned int flags;

  int          plugin_instance_handle;
  int          browser_instance_handle;
}
MPlugIn_Opening;

/* Request Plug-In to close */

#define Message_PlugIn_Close                       0x4d542

#define MPlugIn_Close_WouldLikePlugInToExit        (1u<<0)

typedef struct MPlugIn_Close
{
  unsigned int flags;

  int          plugin_instance_handle;
  int          browser_instance_handle;
}
MPlugIn_Close;

/* Plug-In closing */

#define Message_PlugIn_Closed                      0x4d543

#define MPlugIn_Closed_PlugInWillExitAfterThis     (1u<<0)
#define MPlugIn_Closed_NotAReply                   (1u<<1)
#define MPlugIn_Closed_ErrorHeldInMessageBlock     (1u<<2)

typedef struct MPlugIn_Closed
{
  unsigned int flags;

  int          plugin_instance_handle;
  int          browser_instance_handle;

  int          errnum;
  char         errmess[sizeof(WimpMessage) - 36];
}
MPlugIn_Closed;

/* Request Plug-In moves */

#define Message_PlugIn_Reshape                     0x4d544

typedef struct MPlugIn_Reshape
{
  unsigned int flags;

  int          plugin_instance_handle;
  int          browser_instance_handle;

  int          parent_window_handle;
  BBox         parent_area;
}
MPlugIn_Reshape;

/* Plug-In requesting that it be resized */

#define Message_PlugIn_ReshapeRequest              0x4d545

typedef struct MPlugIn_ReshapeRequest
{
  unsigned int flags;

  int          plugin_instance_handle;
  int          browser_instance_handle;

  unsigned int width;
  unsigned int height;
}
MPlugIn_ReshapeRequest;

#define MPlugIn_StreamNew_StreamTypeMask           (3u<<0)
#define MPlugIn_StreamNew_StreamTypeNormal         (0u<<0)
#define MPlugIn_StreamNew_StreamTypeSeekOnly       (1u<<0)
#define MPlugIn_StreamNew_StreamTypeAsFile         (2u<<0)
#define MPlugIn_StreamNew_StreamTypeAsFileOnly     (3u<<0)
#define MPlugIn_StreamNew_StreamIsSeekable         (1u<<4)

/* Open a new stream */

#define Message_PlugIn_StreamNew                   0x4d548

typedef struct MPlugIn_StreamNew
{
  unsigned int flags;

  int          plugin_instance_handle;
  int          browser_instance_handle;

  int          plugin_stream_instance_handle;
  int          browser_stream_instance_handle;

  string_value url;

  int          eos;
  int          last_modified;
  int          notify;

  string_value mime_type;
  string_value window_target;
}
MPlugIn_StreamNew;

/* Close a stream */

#define Message_PlugIn_StreamDestroy               0x4d549

#define MPlugIn_StreamDestroy_Reason_Success       0
#define MPlugIn_StreamDestroy_Reason_Error         1
#define MPlugIn_StreamDestroy_Reason_User          2

typedef struct MPlugIn_StreamDestroy
{
  unsigned int flags;

  int          plugin_instance_handle;
  int          browser_instance_handle;

  int          plugin_stream_instance_handle;
  int          browser_stream_instance_handle;

  string_value url;

  int          eos;
  int          last_modified;
  int          notify;

  int          reason;
}
MPlugIn_StreamDestroy;

/* Confirm file has been written */

#define Message_PlugIn_StreamAsFile                0x4d54c

typedef struct MPlugIn_StreamAsFile
{
  unsigned int flags;

  int          plugin_instance_handle;
  int          browser_instance_handle;

  int          plugin_stream_instance_handle;
  int          browser_stream_instance_handle;

  string_value url;

  int          eos;
  int          last_modified;
  int          notify;

  string_value pathname;
}
MPlugIn_StreamAsFile;

/* Plug-In URL request */

#define Message_PlugIn_URLAccess                   0x4d54d

#define MPlugIn_URLAccess_ReturnNotifyWhenComplete (1u<<0);
#define MPlugIn_URLAccess_POSTToURL                (1u<<1);
#define MPlugIn_URLAccess_POSTAFile                (1u<<2);

typedef struct MPlugIn_URLAccess
{
  unsigned int flags;

  int          plugin_instance_handle;
  int          browser_instance_handle;

  string_value url;
  string_value target;

  int          notify_data;
  int          data_length;
  string_value data_pointer;
}
MPlugIn_URLAccess;

/* Plug-In status message */

#define Message_PlugIn_Status                      0x4d54f

typedef struct MPlugIn_Status
{
  unsigned int flags;

  int          plugin_instance_handle;
  int          browser_instance_handle;

  string_value status;
}
MPlugIn_Status;

/* Plug-In busy / idle indication */

#define Message_PlugIn_Busy                        0x4d550

#define MPlugIn_Busy_IsBusy                        (1u<<0);
#define MPlugIn_Busy_StatusWordIsValid             (1u<<1);

#define MPlugIn_Busy_State_Stop                    0;
#define MPlugIn_Busy_State_Play                    1;
#define MPlugIn_Busy_State_Pause                   2;
#define MPlugIn_Busy_State_FastForward             3;
#define MPlugIn_Busy_State_Rewind                  4;
#define MPlugIn_Busy_State_Record                  5;

typedef struct MPlugIn_Busy
{
  unsigned int flags;

  int          plugin_instance_handle;
  int          browser_instance_handle;

  unsigned int state;
}
MPlugIn_Busy;

/* Parameters file definitions */

#define PlugIn_ParamType_Terminator      0
#define PlugIn_ParamType_DataFromPARAM   1
#define PlugIn_ParamType_URLFromPARAM    2
#define PlugIn_ParamType_ObjectFromPARAM 3
#define PlugIn_ParamType_BrowserSpecial  4
#define PlugIn_ParamType_DataFromOBJECT  5
#define PlugIn_ParamType_URLFromOBJECT   6
#define PlugIn_ParamType_DataFromAPPLET  5
#define PlugIn_ParamType_URLFromAPPLET   6

/* Function prototypes */

const char      * plugin_return_string                (WimpMessage * m, string_value * sv);
_kernel_oserror * plugin_write_params                 (browser_data * b, HStream * t, char * buffer, int buffer_size, BBox * position);

_kernel_oserror * plugin_add_queue_item               (browser_data * b, HStream * t, BBox * position);
_kernel_oserror * plugin_remove_item                  (plugin_queue * remove);
_kernel_oserror * plugin_flush_queue                  (browser_data * b, int start_now);

_kernel_oserror * plugin_open_bounced                 (WimpMessage * m);
_kernel_oserror * plugin_got_opening                  (WimpMessage * m);
_kernel_oserror * plugin_send_close                   (unsigned int b, unsigned int task, unsigned int instance);

_kernel_oserror * plugin_got_reshape_request          (WimpMessage * m);
_kernel_oserror * plugin_send_original_reshape        (unsigned int b, unsigned int task, unsigned int instance, BBox * position);

_kernel_oserror * plugin_got_url_access               (WimpMessage * m);

_kernel_oserror * plugin_got_status                   (WimpMessage * m);
_kernel_oserror * plugin_got_busy                     (WimpMessage * m);

_kernel_oserror * plugin_setup_stream                 (unsigned int owner, browser_data * fetcher, const char * url);
_kernel_oserror * plugin_start_new_stream             (unsigned int b, const char * data, unsigned int instance, unsigned int task);
_kernel_oserror * plugin_send_original_stream_new     (browser_data * b);
_kernel_oserror * plugin_got_stream_new               (WimpMessage * m);
_kernel_oserror * plugin_stream_new_bounced           (WimpMessage * m);
_kernel_oserror * plugin_send_original_stream_destroy (browser_data * b, int reason);
_kernel_oserror * plugin_abort_stream                 (browser_data * b);
_kernel_oserror * plugin_fetch_completed              (browser_data * b);

_kernel_oserror * plugin_obtain_instance              (browser_data * b, HStream * t, unsigned int * instance);
void              plugin_flush_instance_entries       (browser_data * b);

void              plugin_shutdown                     (void);