/*
 *  ESNetscapePluginView.h
 *  Flash'In'App
 *
 *  Copyright 2008 Eltima Software. All rights reserved.
 *
 *	Flash'In'App is free for non-commercial use.
 *	If you plan to integrate it in commercial software, please, make sure you are acquainted with the license terms and obtain the Commercial License.
 *	Please, contact Eltima at sales@eltima.com or visit http://mac.eltima.com
 */

#ifndef __LP64__

#import <Cocoa/Cocoa.h>
#import <AGL/agl.h>

#import "ESNetscapePlugin.h"
#import "ESNetscapePluginStream.h"
#import "npfunctions.h"
#import "npapi.h"

typedef union PluginPort {
#ifndef NP_NO_QUICKDRAW
    NP_Port qdPort;
#endif        
    NP_CGContext cgPort;
    NP_GLContext aglPort;
} PluginPort;

/*
 * external data loading types
 * StreamLoadType_None - do not load data
 * StreamLoadType_Internal - allow loading data by Flash'In'App itself
 * StreamLoadType_External - allow loading data by delegate
 */
typedef enum _StreamLoadType
{
	StreamLoad_None = 0,
	StreamLoad_Internal,
	StreamLoad_External
}StreamLoadType;

/*
 * target types which will be passed to netscapeView:shouldLoadRequest:onTarget:
 */
typedef enum _TargetsValues
{
  Target_None = -2,
  Target_Null = -1,
  Target_Blank,
  Target_New,
  Target_Top,
  Target_Self,
  Target_Current,
  Target_Parent,
  Target_Count
}TargetsValues;

@interface ESNetscapePluginView : NSView
{
	id delegate;
  ESNetscapePlugin *pluginPackage;
    
  NSURL *sourceURL;

	int mode;
	
	unsigned argsCount;
	char **cAttributes;
	char **cValues;
			
	NPP plugin;
	NPWindow window;
	NPWindow lastSetWindow;
	PluginPort nPort;
	PluginPort lastSetPort;
	NPDrawingModel drawingModel;
	
	// These are only valid when drawingModel is NPDrawingModelOpenGL
	AGLContext aglContext;
	NSWindow *aglWindow;

#ifndef NP_NO_QUICKDRAW
	// This is only valid when drawingModel is NPDrawingModelQuickDraw
	GWorldPtr offscreenGWorld;
#endif

	BOOL isStarted;
	BOOL inSetWindow;
	BOOL suspendKeyUpEvents;
	BOOL hasFocus;
	BOOL isTransparent;
	BOOL shouldStopSoon;

	unsigned pluginFunctionCallDepth;

	int32 specifiedHeight;
	int32 specifiedWidth;

	NSString *MIMEType;
	NSURL *baseURL;
	NSTrackingRectTag trackingTag;
	NSTimer *nullEventTimer;
	
	NPP_NewProcPtr NPP_New;
	NPP_DestroyProcPtr NPP_Destroy;
	NPP_SetWindowProcPtr NPP_SetWindow;
	NPP_NewStreamProcPtr NPP_NewStream;
	NPP_DestroyStreamProcPtr NPP_DestroyStream;
	NPP_StreamAsFileProcPtr NPP_StreamAsFile;
	NPP_WriteReadyProcPtr NPP_WriteReady;
	NPP_WriteProcPtr NPP_Write;
	NPP_PrintProcPtr NPP_Print;
	NPP_HandleEventProcPtr NPP_HandleEvent;
	NPP_URLNotifyProcPtr NPP_URLNotify;
	NPP_GetValueProcPtr NPP_GetValue;
	NPP_SetValueProcPtr NPP_SetValue;
  NP_DisableLocalSecurityPtr NP_DisableLocalSecurity;
  NP_EnforceLocalSecurityPtr NP_EnforceLocalSecurity;
	
	EventHandlerRef keyEventHandler;

  NSMutableArray *streams;
	
  BOOL sendRightClick;
  NSColor *bgColor;
	NSImage *bgImage;
	
	NPObject *windowScriptObject;
}

/*
 * init method, initWithFrame method is not realized
 * NOTE: you shouldn't create the object of this type directly; instead use [ESFlashView initWithFrame:]
 */
- (id)initWithFrame:(NSRect)frame
      pluginPackage:(ESNetscapePlugin *)thePluginPackage
           MIMEType:(NSString *)MIME
      attributeKeys:(NSArray *)keys
    attributeValues:(NSArray *)values
       loadManually:(BOOL)loadManually;

/*
 * set/get background color of the View when nothing is loaded
 */
- (NSColor *)backgroundColor;
- (void) setBackgroundColor:(NSColor *)aColor;

/*
 * set/get background image of the View when nothing is loaded
 */
- (NSImage *)backgroundImage;
- (void) setBackgroundImage:(NSImage*)image;

/*
 * turn transparency on/off
 * must be called before loading movie
 * default value is "NO"
 * NOTE: should you change the transparency settings in runtime, you should reload the movie (loadMovie:atURL:withBaseURL:) 
 */
- (void)setTransparent:(BOOL)transparent;
- (BOOL)isTransparent;

/*
 * redirect Right-button mouse clicks to Netscape plugin
 * if YES, plugin's context menu will be activated
 
 * sendRightClick - gets the current value of this settings
 * setSendRightClick: - sets the new value for this setting
 */
- (BOOL) sendRightClick;
- (void) setSendRightClick:(BOOL)value;

/*
 * get the snapshot of the current frame, the object with the image of the current frame will be returned
 */
- (NSImage *) snapshot;

/*
 * get the snapshot of the current frame in the specified rectangle (crop frame), the object with the 
 * image of the current frame (in the receiver's coordinates) will be returned
 */
- (NSImage *) snapshotFromRect:(NSRect) sourceRect;

/*
 * load file into plugin
 * movieData - file contents
 * movieURL - URL to file
 * movieBaseURL - base URL to file (may be nil)
 */
- (BOOL) loadMovie:(NSData *)movieData atURL:(NSURL *)movieURL withBaseURL:(NSURL *)movieBaseURL;

/*
 * set/get delegate object
 
 * delegate - gets the current value of the setting
 * setDelegate - sets the new value for this setting
 */
- (id) delegate;
- (void) setDelegate:(id)value;

/*
 * load and launch the plugin
 * Note: this is done automatically with loadMovie:atURL:withBaseURL:
 */
- (BOOL)start;

/*
 * check if plugin is running
 */
- (BOOL)isStarted;

/*
 * stop and try unloading plugin
 
 * NOTE: by trying to unload the plugin we mean that in case there are several Netscape plugin views running that use the same plugin,
 * it will be unloaded when all the views are stopped
 */
- (void)stop;

/*
 * internal use only, should not be publicly accessed
 */
- (NPP)plugin;

/*
 * internal use only, should not be publicly accessed
 */
- (ESNetscapePlugin *)pluginPackage;
- (void)setPluginPackage:(ESNetscapePlugin *)thePluginPackage;
- (void)setMIMEType:(NSString *)theMIMEType;

/*
 * internal use only, should not be publicly accessed
 */
- (void)setAttributeKeys:(NSArray *)keys andValues:(NSArray *)values;
- (void)setMode:(int)theMode;

/*
 * set/get base URL
 
 * base URL - it's the URL where resources will be searched for in case the movie loads them by relative paths; it's the host URL which
 * user accesses to see the movie, not the one it is physically located at
 
 * setBaseURL: - sets the new base URL (may be nil)
 
 * baseURL - returns current value of base URL
 */
- (void)setBaseURL:(NSURL *)theBaseURL;
- (NSURL *) baseURL;

/*
 * set/get URL to file
 
 * URL to file - it's the URL where the movie is physically stored, not where it is loaded from
 
 * setSourceURL: - sets the new URL to file (cannot be nil)
 
 * sourceURL - returns current value of URL to file
 */
- (void)setSourceURL:(NSURL *)theSourceURL;
- (NSURL *) sourceURL;

/*
 * these methods actually call plugin's functions with the 'name' name via 'invoke'
 * for instance, Flash plugin will have Play, IsPlaying, StopPlay functions
 
 * the first method calls this function without arguments
 * the second method calls this function with one argument
 * the last one calls this function with several (array of) arguments
 */
- (id) invokeFunction:(NSString *)name;
- (id) invokeFunction:(NSString *)name withArgument:(id)argument;
- (id) invokeFunction:(NSString *)name withArguments:(NSArray *)arguments;

@end

@interface NSObject (NetscapePluginViewDelegate)
/*
 * this method is called when plugin wants to receive UserAgent string from the host application
 * Note: do not use this method, unless you are sure what you are doing
 */
- (NSString *)userAgentStringForNetscapeView:(ESNetscapePluginView *)netscapeView;

/*
 * this mehthod is called when netscapeView is trying to load the data for 'request' 
 * if target == Target_Null - plugin wants to load data into itself, otherwise it's an attempt to open a web-page
 */
- (StreamLoadType) netscapeView:(ESNetscapePluginView *)netscapeView shouldLoadRequest:(NSURLRequest *)request onTarget:(TargetsValues)target;

/*
 * these methods are called only if netscapeView:shouldLoadRequest:onTarget: returns StreamLoadType_Internal
 * are called during the start (netscapeView:startLoadingRequest:), end (netscapeView:finishLoadingRequest:) 
 * or loading error (netscapeView:failLoadingRequest:)
 */
- (void) netscapeView:(ESNetscapePluginView *)netscapeView startLoadingRequest:(NSURLRequest *)request;
- (void) netscapeView:(ESNetscapePluginView *)netscapeView finishLoadingRequest:(NSURLRequest *)request;
- (void) netscapeView:(ESNetscapePluginView *)netscapeView failLoadingRequest:(NSURLRequest *)request withError:(NSError *)error;

/*
 * these methods are called only if netscapeView:shouldLoadRequest:onTarget: returns StreamLoadType_External 
 * delegate should call the following sequence of methods, for example:
 * [stream startStreamWithResponse:response] - when it receives a response for [stream requestURL]
 * [stream receivedData:data] - to pass the data into plugin (data type should be NSData)
 * [stream finishedLoadingWithData:nil] - when data loading is finished
 */
- (void) netscapeView:(ESNetscapePluginView *)netscapeView loadStream:(ESNetscapePluginStream *)stream;

@end

#endif
