/*
* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  Acts as an adapter between plugin and browser.
*
*/

// INCLUDE FILES
#include "../../bidi.h"

#include <e32std.h>
#include <e32def.h>
#include <eikdef.h>
#include <eikenv.h>
#include <eikappui.h>
#include <SysUtil.h>
#include <AknUtils.h>

#include "WebFrame.h"
#include "HttpDefs.h"
#include <brctldefs.h>
#include "StaticObjectsContainer.h"
#include <pluginadapterinterface.h>
#include "PluginWin.h"
#include "PluginSkin.h"
#include "PluginHandler.h"
#include "PluginStream.h"
#include "WebView.h"
#include "WebFrameView.h"
#include "WebSurface.h"
#include "BrCtl.h"
#include "Frame.h"
#include "WebCursor.h"
#include "WebPointerEventHandler.h"
#include "WebPageScrollHandler.h"
#include "WebKitLogger.h"
#include "WebCoreGraphicsContext.h"

#include <rt_gestureif.h>

using namespace WebCore;
using namespace RT_GestureHelper;
using namespace stmGesture; 
// CONSTANTS
const TInt KPluginGranularity = 3;
_LIT(KPath,"c:\\system\\temp\\");

void panicPlugin(TInt error = KErrNone)
{
    User::Panic(_L("Plugin Handling Panic"), error);
}

// -----------------------------------------------------------------------------
// PluginWin::PluginWin
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
PluginWin::PluginWin(PluginSkin* pluginskin)
    : m_pluginskin(pluginskin)
    , m_windowedPlugin(true), m_fullscreen(false), m_windowCreated(false), m_visibilty(false)
{
}

// -----------------------------------------------------------------------------
// PluginWin::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
void PluginWin::ConstructL( const WebView& view )
{
    if (m_windowedPlugin) {
        CreateWindowL((CCoeControl*)&view);
        ActivateL();
		m_windowCreated = true;
    } else {
        SetContainerWindowL(*view.brCtl()->CCoeControlParent());
        m_bitmap = new (ELeave) CFbsBitmap();
        TDisplayMode mode = m_transparentPlugin ? EColor16MA : WebCore::StaticObjectsContainer::instance()->webSurface()->displayMode();
        m_bitmap->Create(TSize(0,0), mode);
    }
    // Add the focus/foreground observer
    ControlEnv()->AddForegroundObserverL( *this ) ;
    m_pluginHasBitmap = false;
    m_pausedBitmap = NULL;
    m_BitmapSupported = false;
}

// -----------------------------------------------------------------------------
// PluginWin::~PluginWin
// Deconstructor.
// -----------------------------------------------------------------------------
//
PluginWin::~PluginWin()
{
    PluginHandler* pluginHandler = WebCore::StaticObjectsContainer::instance()->pluginHandler();

    int index = pluginHandler->getVisiblePlugins().Find(m_pluginskin);
    if (index != KErrNotFound)
        pluginHandler->getVisiblePlugins().Remove(index);

    TRAP_IGNORE( setPluginFocusL( EFalse ) );

    // Remove the foreground observer
    ControlEnv()->RemoveForegroundObserver( *this );
    delete m_bitmap;
   if (m_pausedBitmap)
        {
        delete m_pausedBitmap;
        }
}

// -----------------------------------------------------------------------------
// PluginWin::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
PluginWin* PluginWin::NewL( PluginSkin* pluginskin,
                            const WebView& view  )
{
    PluginWin* self = new( ELeave ) PluginWin(pluginskin);
    return self;
}

// -----------------------------------------------------------------------------
// PluginWin::PositionChanged
// Update the size of the control.
// -----------------------------------------------------------------------------
//
void PluginWin::PositionChanged()
{
    windowChanged();
}

// -----------------------------------------------------------------------------
// PluginWin::SizeChanged
// Update the size of the control.
// -----------------------------------------------------------------------------
//
void PluginWin::SizeChanged()
{
    windowChanged();
}

void PluginWin::windowChanged()
{
    TRAPD(ret, windowChangedL());
    if (ret != KErrNone) {
        delete m_bitmap;
        m_bitmap = NULL;
    }
    if (m_forceScroll)
    	m_forceScroll = EFalse;
}

void PluginWin::windowChangedL()
{
    if (m_fullscreen) return;
    PlayPausePluginL();
    if (m_pluginskin->getNPPluginFucs() && m_pluginskin->getNPPluginFucs()->setwindow ){
        NPWindow  window;
    TRect rect( m_pluginskin->getPluginWinRect() );
    TRect clipRect = m_pluginskin->getClipRect();
    TRect myRect = Rect();
        if (!m_windowedPlugin) {
            myRect.Move(-myRect.iTl.iX, -myRect.iTl.iY); // windowed CCoeControl uses its own coordinates
        }
    TRect passedRect = clipRect;
    passedRect.Intersection(rect);
    TPoint tl = myRect.iTl - passedRect.iTl;
        // Coordinates for the plugin always start from (0,0) and are relative
        // to the parent CCoeControl
        rect.Move(tl);
        clipRect.Move(tl);
        clipRect.Intersection(myRect);
        window.x = rect.iTl.iX;
        window.y = rect.iTl.iY;
        window.width = rect.Width();
        window.height = rect.Height();
        window.type = m_windowedPlugin ? NPWindowTypeWindow : NPWindowTypeDrawable ;
        clipRect.iTl.iX = Max(clipRect.iTl.iX, 0);
        clipRect.iTl.iY = Max(clipRect.iTl.iY, 0);
        clipRect.iBr.iX = Max(clipRect.iBr.iX, 0);
        clipRect.iBr.iY = Max(clipRect.iBr.iY, 0);
        window.clipRect.top = clipRect.iTl.iY;
        window.clipRect.left = clipRect.iTl.iX;
        window.clipRect.bottom =clipRect.iBr.iY;
        window.clipRect.right = clipRect.iBr.iX;

        if (m_windowedPlugin) {
             window.window =  (MPluginAdapter*)this;
        } else {
             m_bitmap->Resize(rect.Size());
             window.window = (CFbsBitmap*)m_bitmap;
        }
		if (!m_windowedPlugin || m_windowCreated)
			m_pluginskin->getNPPluginFucs()->setwindow(m_pluginskin->getNPP(), &window );

    }
}

// -----------------------------------------------------------------------------
// PluginWin::ProcessEventL
// Procces a user interface event.
// -----------------------------------------------------------------------------
//
void PluginWin::processEventL( TPluginEventType eventType,
                                TBool& consumed )
{
    consumed = EFalse;

    switch ( eventType ) {
        case EEventActivate:
        {
            WebCursor* cursor = StaticObjectsContainer::instance()->webCursor();
            CBrCtl*   brCtl = control(m_pluginskin->frame());    
            WebView*  view = brCtl->webView();

            if ( m_notifier )
            {
            TPoint pt = TPoint(0,0); 
            if (cursor) {
                pt = cursor->position() + view->PositionRelativeToScreen() - 
                        m_control->PositionRelativeToScreen();
                }
            m_notifier->NotifyL( MPluginNotifier::EPluginActivated, (void*) &pt );
            cursor->cursorUpdate(EFalse);
            consumed = ETrue;
            setPluginFocusL( ETrue );
            m_pluginskin->pluginFocusChanged(ETrue);
            }

            else
            {
            m_pluginskin->frame()->frameView()->topView()->setFocusedElementType(TBrCtlDefs::EElementBrokenImage);
            cursor->cursorUpdate(ETrue);
            consumed = EFalse;     
            setPluginFocusL( EFalse );
            }
            break;
        }
        case EEventDeactivate:
                if( m_notifier )
                {
                    m_notifier->NotifyL( MPluginNotifier::EPluginDeactivated, (void*) 0 );
                }
            consumed = ETrue;
            setPluginFocusL( EFalse );
        break;

        case EEventLoseFocus:
        if ( m_notifier ) {
            HandleLosingForeground();
            consumed = ETrue;
        }
        break;

        case EEventGainFocus:
            HandleGainingForeground();
            consumed = ETrue;
        break;

        default:
        break;
    }

}


// -----------------------------------------------------------------------------
// PluginWin::OfferKeyEventL
// Hands a key event to the control.
// -----------------------------------------------------------------------------
//
TKeyResponse PluginWin::OfferKeyEventL( const TKeyEvent& aKeyEvent,
                                         TEventCode aType )
{
    TKeyResponse ret = EKeyWasNotConsumed;
    if ( m_control ) {
        ret = m_control->OfferKeyEventL( aKeyEvent, aType );
    }
    else if (!m_windowedPlugin && m_pluginskin->getNPPluginFucs() && m_pluginskin->getNPPluginFucs()->event) {
        WebCursor* c = StaticObjectsContainer::instance()->webCursor();
        TPoint pt = (c->position());
        pt = m_pluginskin->frame()->frameView()->viewCoordsInFrameCoords(pt);
        pt -= m_pluginskin->rect().iTl;
        NPEvent event;
        NPEventKey eventKey;
        event.event = ENppEventKey;
        eventKey.keyEvent = &aKeyEvent;
        eventKey.type = aType;
        eventKey.reserved = static_cast<void*>(&pt);
        event.param = &eventKey;
        ret = (TKeyResponse)m_pluginskin->getNPPluginFucs()->event(m_pluginskin->getNPP(), static_cast<void*>(&event));
    }
    return ret;
}


// -----------------------------------------------------------------------------
// PluginWin::ComponentControl
// Return the child control by index.
// -----------------------------------------------------------------------------
//
CCoeControl* PluginWin::ComponentControl( TInt /*aIndex*/ ) const
{
    return 0;
}
// -----------------------------------------------------------------------------
// PluginWin::CountComponentControls
// Return the number of child controls.
// -----------------------------------------------------------------------------
//
TInt PluginWin::CountComponentControls() const
{
    return 0;
}

//-------------------------------------------------------------------------------
// HandlePointerEventL
// Handles Pointer Events
//-------------------------------------------------------------------------------
void PluginWin::HandlePointerEventL(const TPointerEvent& aPointerEvent)
{
    if (!m_windowedPlugin && m_pluginskin->getNPPluginFucs() && m_pluginskin->getNPPluginFucs()->event) {
        NPEvent event;
        NPEventPointer ep;
        event.event = ENppEventPointer;

        TPoint pt;
        if (m_pluginskin->pluginPlayer()) {
            pt = aPointerEvent.iPosition;
            pt -= Rect().iTl;
            pt = m_pluginskin->frame()->frameView()->toDocCoords(pt);
        }
        else {
            pt = m_pluginskin->frame()->frameView()->viewCoordsInFrameCoords(aPointerEvent.iPosition);
            pt -= m_pluginskin->rect().iTl;
        }
        TPointerEvent pe(aPointerEvent);
        pe.iPosition = pt;

        ep.pointerEvent = &pe;
        ep.reserved = NULL;
        event.param = &ep;
        m_pluginskin->getNPPluginFucs()->event(m_pluginskin->getNPP(), static_cast<void*>(&event));
    }
}

// -----------------------------------------------------------------------------
// PluginWin::RefreshPlugin
//
// Refresh the plugin. - Called by PluginSkin
// -----------------------------------------------------------------------------
//
TInt PluginWin::refreshPlugin(CFbsBitGc& bitmapContext,TRect aRect)
{
    if (m_control && IsVisible() && m_control->DrawableWindow())
        m_control->DrawNow();
    if (!m_windowedPlugin && m_bitmap) {
        NPEvent event;
        event.event = ENppEventDraw;
        event.param = 0;
        if (m_pluginskin->getNPPluginFucs() && m_pluginskin->getNPPluginFucs()->event) {
            m_pluginskin->getNPPluginFucs()->event(m_pluginskin->getNPP(), static_cast<void*>(&event));
        }
        bitmapContext.DrawBitmap(aRect, m_bitmap);
    }
    return KErrNone;
}

// -----------------------------------------------------------------------------
// PluginWin::MakeVisible
//
// Hides or shows the PluginInst.
// -----------------------------------------------------------------------------
//
void PluginWin::makeVisible( TBool visible )
    {
    WebView* view = control(m_pluginskin->frame())->webView();
    if(!view)
        return;
    
    if((!m_pluginHasBitmap) && (IsVisible() != visible) && (!view->isPinchZoom()))
    {
        CCoeControl::MakeVisible(visible);
    }
    
    PluginHandler* pluginHandler = WebCore::StaticObjectsContainer::instance()->pluginHandler();
    int index = pluginHandler->getVisiblePlugins().Find(m_pluginskin);
    if (visible && (m_visibilty != visible) && (index == KErrNotFound)) {
        pluginHandler->getVisiblePlugins().AppendL(m_pluginskin);
        m_visibilty = visible;
    }
    else if (!visible && (index != KErrNotFound)) {
        pluginHandler->getVisiblePlugins().Remove(index);
        m_visibilty = visible;
    }
    
    NotifyPluginVisible(visible);
    if (!m_windowedPlugin && m_pluginskin->getNPPluginFucs() && m_pluginskin->getNPPluginFucs()->event) {
        NPEvent event;
        NpEventVisibility ev;
        event.event = ENppEventVisibility;
        ev.visible = visible;
        ev.reserved = 0;
        event.param = &ev;
        m_pluginskin->getNPPluginFucs()->event(m_pluginskin->getNPP(), static_cast<void*>(&event));
    }
}

// -----------------------------------------------------------------------------
// PluginWin::HandleControlEventL
//
// Handles an event from an observed control.
// -----------------------------------------------------------------------------
//
void PluginWin::HandleControlEventL( CCoeControl* /*aControl*/,
                                      TCoeEvent /*aEventType*/ )
{
}


// -----------------------------------------------------------------------------
// PluginWin::SetPluginFocusL
// Give or take focus from the plugin. The calls AddToStackL or RemoveFromStackL
// will cause the CCoeControl architecture to call SetFocus, which will end up
// calling ViewFocusChanged().
// -----------------------------------------------------------------------------
//
void PluginWin::setPluginFocusL(TBool focus)
{
    if (focus) {

        if (!m_pluginfocus) {
            m_pluginfocus = ETrue;
            iEikonEnv->EikAppUi()->AddToStackL(this);
            SetFocus(ETrue);
        }
    }
    else {

        if (m_pluginfocus) {
            m_pluginfocus = EFalse;
            iEikonEnv->EikAppUi()->RemoveFromStack( this );
            SetFocus(EFalse);
        }
    }
}


// -----------------------------------------------------------------------------
// PluginWin::ResizePluginRect
//
// Resize the plugin rect. This requires that we set the iRect and re-layout
// the render object.
// -----------------------------------------------------------------------------
//
void PluginWin::resizePluginRect(TRect& rect)
{
    // Get our current rect
    TRect skinRect( m_pluginskin->rect() );

    // If the rect sizes are the same, we don't need to save and relayout
    if (skinRect.Size() == rect.Size()) {
        return;
    }

    // Set the PluginSkin rect, used by WebCore and PluginWin for layout.
    // The adjusted rect has the new size, but same starting point
    TRect adjustedRect (skinRect.iTl, rect.Size() );
    m_pluginskin->setRect(adjustedRect);

    m_pluginskin->resized();
}

// -----------------------------------------------------------------------------
// PluginWin::HandleGainingForeground
// -----------------------------------------------------------------------------
//
void PluginWin::HandleGainingForeground()
{
    if (m_notifier) {
        if(m_pluginHasBitmap)
            { 
            ClearPluginBitmap(); 
            m_pluginskin->activateVisiblePlugins(); 
            }
        TRAP_IGNORE(m_notifier->NotifyL(MPluginNotifier::EApplicationFocusChanged, (void*)1));
    }
}

// -----------------------------------------------------------------------------
// PluginWin::HandleLosingForeground
// -----------------------------------------------------------------------------
//
void PluginWin::HandleLosingForeground()
{
    if (m_notifier) {
        TRAP_IGNORE(m_notifier->NotifyL(MPluginNotifier::EApplicationFocusChanged, (void*)0));
    }
}


// Functions from MPluginAdapter
HBufC8* PluginWin::PluginDataUrl()
{
    if (m_pluginskin)
        return m_pluginskin->url();
    return NULL;
}

// -----------------------------------------------------------------------------
// PluginWin::addPluginOptionsL
//
// Add the Option Menu items to the menuPane, these will be handled by the
// plugin. The menu items are added in this method and then handled in the
// HandlePluginCommandL method. If the Option Menu Handler is not defined, then
// the plugin doesn't handle custom menu commands.
// -----------------------------------------------------------------------------
//
void PluginWin::addPluginOptionsL(CEikMenuPane& menuPane, TInt commandBase, TInt after)
    {
    if (m_optionmenuhandler)
        {
        m_optionmenuhandler->AddPluginOptionMenuItemsL(menuPane, commandBase, after);
        }
    }

// -----------------------------------------------------------------------------
// PluginWin::handlePluginCommandL
//
// Add the Option Menu items to the menuPane, these will be handled by the
// plugin. The menu items are added in this method and then handled in the
// HandlePluginCommandL method. If the Option Menu Handler is not defined, then
// the plugin doesn't handle custom menu commands.
// -----------------------------------------------------------------------------
//
void PluginWin::handlePluginCommandL(TInt id)
    {
    if (m_optionmenuhandler)
        {
        m_optionmenuhandler->HandlePluginCommandL(id);
        }
    }


// -----------------------------------------------------------------------------
//
NPObject* PluginWin::windowScriptNPObject()
    {
    Frame* f = core(m_pluginskin->frame());
    if (f)
        return f->windowScriptNPObject();
    return 0;
    }


// -----------------------------------------------------------------------------
// PluginWin::ForceRedraw
// -----------------------------------------------------------------------------
//
void PluginWin::forceRedraw(bool drawNow)
    {
    if (m_pluginskin->pluginPlayer()) {
        DrawNow();
    }
    else {
        WebFrame* mf = (m_pluginskin->frame());
        if (mf && mf->frameView()) {
            WebFrameView* fv = mf->frameView();
            TRect rect(Rect());
            rect = TRect(fv->viewCoordsInFrameCoords(Rect().iTl), fv->viewCoordsInFrameCoords(Rect().iBr));
            fv->invalidateRect(rect, drawNow);
        }
    }
}

// -----------------------------------------------------------------------------
// CPluginWin::MoveWindow
// Move/scroll window by aOffset and also sets the current cursor position
// -----------------------------------------------------------------------------
//
void PluginWin::moveWindow(const TPoint& aOffset)
    {
    // set force scroll to true, when plugin gives move command, 
    // browser needs to move window according to offset value
    m_forceScroll = ETrue;
    // This plug-in has focus, so hide the Browser's cursor. The Plugin
    // can display its own cursor, if it needs one.

    WebFrame* mf = mainFrame(m_pluginskin->frame());
    WebCursor* c = StaticObjectsContainer::instance()->webCursor();
    if (c && mf && mf->frameView() && !m_pluginskin->pluginPlayer())
        {
            // Offset sent by plugins doesn't take care of zoom level. Calculate currect offset value
            WebView *view = control(m_pluginskin->frame())->webView();
            TInt zoomlevel = view->zoomLevel();
		    TPoint oldPos(mf->frameView()->contentPos());
		    TPoint newPos ((aOffset.iX  * 100)/zoomlevel, (aOffset.iY  * 100)/zoomlevel);
	        c->offsetCursor( aOffset );
            mf->frameView()->scrollTo(oldPos + newPos);
            view->scrollStatus(false); 
            c->cursorUpdate(EFalse);        
        }

    }

// -----------------------------------------------------------------------------
// CPluginWin::PluginDeactivate
// Deactivate the plugin
// -----------------------------------------------------------------------------
//
void PluginWin::pluginDeactivate(const TPoint& aPosition)
{
    m_pluginskin->deActivate();
    if (!m_pluginskin->isActive()) {
        CBrCtl*   brCtl = control(m_pluginskin->frame());
        WebView*  view = brCtl->webView();
        TPoint pos = aPosition + m_control->PositionRelativeToScreen() - 
                     view->PositionRelativeToScreen();
        WebCursor* cursor = StaticObjectsContainer::instance()->webCursor();
        TPoint offset = cursor->position() - pos;
        cursor->offsetCursor( offset );
        cursor->cursorUpdate(ETrue);        
    }
}

// -----------------------------------------------------------------------------
// CPluginWin::HitRegionContains
// -----------------------------------------------------------------------------
//
TBool PluginWin::HitRegionContains(const TPoint &aPoint, const CCoeControl &/*aControl*/) const
    {
    PluginHandler* pluginHandler = WebCore::StaticObjectsContainer::instance()->pluginHandler();
    pluginHandler->setPluginToActivate(NULL);

    if (m_pluginskin->frame()->frameView()->topView()->focusedElementType() != TBrCtlDefs::EElementActivatedObjectBox)
        {

        if ( !m_pluginskin->CanInteract() && !m_pluginskin->pluginPlayer() )
        {
            m_pluginskin->activate();
        }
        else {
            /* We are storing  plugin that we want to acrivate here 
             * When we get to WebPointerEventHandler::HandleGesture() we will check
             * if this pointer != NULL and will send mousePress event to WebCore.
             * This will trigger the plugin activation.
             */         
            pluginHandler->setPluginToActivate(m_pluginskin);
        TPoint point = m_pluginskin->getPluginWinRect().iTl + aPoint;

        // Plugin gets pointer event. Activate plugin
	      control(m_pluginskin->frame())->webView()->setFocusNone();

        WebCursor* cursor = StaticObjectsContainer::instance()->webCursor();
        cursor->setPosition(point);
        }
        }
    return ETrue;
    }


// -----------------------------------------------------------------------------
// CPluginWin::PluginConstructedL
//
// Notify the associated PluginInst that it's control has been created.
// -----------------------------------------------------------------------------
//
void PluginWin::PluginConstructedL( CCoeControl *aControl )
    {
    m_control = aControl;
    aControl->SetHitTest(this);
    }

// -----------------------------------------------------------------------------
// CPluginWin::Draw
//
// Draw the plugin, called only when in the PluginPlayer.
// -----------------------------------------------------------------------------
//
void PluginWin::Draw( const TRect& /*rect*/ ) const
{
    if (m_pluginskin->pluginPlayer() && !m_windowedPlugin && m_bitmap) {
        NPEvent event;
        event.event = ENppEventDraw;
        event.param = 0;
        if (m_pluginskin->getNPPluginFucs() && m_pluginskin->getNPPluginFucs()->event) {
            m_pluginskin->getNPPluginFucs()->event(m_pluginskin->getNPP(), static_cast<void*>(&event));
        }
        CWindowGc& gc = SystemGc();
        gc.BitBlt(Rect().iTl, m_bitmap);
    }
}

void PluginWin::ToggleScreenMode(bool aFullScreen)
{
  m_fullscreen = aFullScreen;
  CBrCtl*   brCtl = control(m_pluginskin->frame());
  WebCursor* cursor = StaticObjectsContainer::instance()->webCursor();
  
  cursor->cursorUpdate(!aFullScreen && !AknLayoutUtils::PenEnabled());
  StaticObjectsContainer::instance()->setPluginFullscreen(aFullScreen);
  brCtl->reportStateChanged(TBrCtlDefs::EStatePluginFullScreen, m_fullscreen);
}
void PluginWin::adaptiveZoom(const TPoint& aCurPosition)
{
  CBrCtl*   brCtl = control(m_pluginskin->frame());
  WebView*  view = brCtl->webView();
  WebCursor* cursor = StaticObjectsContainer::instance()->webCursor();
  cursor->setPosition(aCurPosition);
  view->setZoomLevelAdaptively();
}
void PluginWin::NotifyPluginVisible (TBool visible)

{
  if(m_notifier)
    {
      if(visible && IsVisible())
      {
        TRAP_IGNORE(m_notifier->NotifyL(MPluginNotifier::EPluginInvisible, (void*)1));
      }
      else
      {
        TRAP_IGNORE(m_notifier->NotifyL(MPluginNotifier::EPluginInvisible, (void*)0));
      }	
    }
}
void PluginWin::PlayPausePluginL ()
{
    if(m_notifier) 
    {
        CBrCtl*   brCtl = control(m_pluginskin->frame());    
        WebView*  view = brCtl->webView();
        TBool scrolling = view->viewIsScrolling();
        if (scrolling) {
            m_notifier->NotifyL( MPluginNotifier::EPluginPause, (void*)1 );
        }
        else {
            m_notifier->NotifyL( MPluginNotifier::EPluginPause, (void*)0 );
        }
    }
}

TBool PluginWin::IsCollectBitmapSupported ()
{
    if(m_notifier) {
        m_BitmapSupported = m_notifier->NotifyL( MPluginNotifier::ECollectBitmapSupported, (void*)0 ) ;
    }
    return m_BitmapSupported;
}


void PluginWin::GetBitmapFromPlugin (bool status)
    {
    if(m_notifier) {
         if (status) {
             //if plugin fails to send bitmap even though the "ECollectBitmapSupported"
             CBrCtl*   brCtl = control(m_pluginskin->frame());    
             WebView*  view = brCtl->webView();
             
             if(view && view->isPinchZoom())
                 m_PluginInvisibleOnPinchZoom = ETrue; 
             m_notifier->NotifyL( MPluginNotifier::ECollectBitmap, (void*)1 );
			 
			 //if Notify CollectBitmap failed to send bitmap to SetBitmapFromPlugin, 
			 //Then forcefully make the plugin window invisible for pinch zoom 
             if(m_PluginInvisibleOnPinchZoom)
                 { 
                 m_PluginInvisibleOnPinchZoom = EFalse; 
                 if (IsVisible())
                     {
                     MakeVisible(false);
                     }
                 }
         }
         else {
             m_notifier->NotifyL( MPluginNotifier::ECollectBitmap, (void*)0 );
             
             m_pluginHasBitmap = 0;
             if(m_pausedBitmap)
                 {
                 delete m_pausedBitmap;
                 m_pausedBitmap = NULL;
                 }
         }
       }
}


void PluginWin::HandlePointerEventFromPluginL(const TPointerEvent& aEvent)
{
    CBrCtl*   brCtl = control(m_pluginskin->frame());    
    WebView*  view = brCtl->webView();
#ifdef BRDO_MULTITOUCH_ENABLED_FF	
    if (aEvent.IsAdvancedPointerEvent()) {
        TAdvancedPointerEvent tadvp = *(static_cast<const TAdvancedPointerEvent *>(&aEvent));
        if (!StaticObjectsContainer::instance()->isPluginFullscreen()) {
            tadvp.iPosition = aEvent.iPosition - view->PositionRelativeToScreen();
        }
        view->pointerEventHandler()->HandlePointerEventL(tadvp);
    }
    else {
#endif 	
        TPointerEvent event(aEvent);
        if (!StaticObjectsContainer::instance()->isPluginFullscreen()) {
            event.iPosition = aEvent.iPosition - view->PositionRelativeToScreen();
        }
        view->pointerEventHandler()->HandlePointerEventL(event);
#ifdef BRDO_MULTITOUCH_ENABLED_FF			
    }
#endif 	
}


TBool PluginWin::HandleGesture(const TStmGestureEvent& aEvent)
{
    TBool ret = EFalse;
    
    TGestureEvent eventForPlugin; 
    switch(aEvent.Code()) 
        {
        case EGestureUidUnknown :
            eventForPlugin.SetCode(EGestureUnknown); 
            break; 
        case EGestureUidTouch :
            eventForPlugin.SetCode(EGestureStart);
            break; 
        case EGestureUidTap : 
            if(aEvent.Type() == ETapTypeSingle)
                eventForPlugin.SetCode(EGestureTap); 
            else 
                eventForPlugin.SetCode(EGestureDoubleTap); 
            break; 
        case EGestureUidLongPress :
            eventForPlugin.SetCode(EGestureLongTap); 
            break; 
        case EGestureUidPan :
            eventForPlugin.SetCode(EGestureDrag);
            break; 
        case EGestureUidRelease :
            eventForPlugin.SetCode(EGestureReleased); 
            break; 
        case EGestureUidFlick :
            eventForPlugin.SetCode(EGestureFlick);
            break; 
        case EGestureUidPinch :
            eventForPlugin.SetCode(EGesturePinch);
            break; 
        default : 
            break; 

        }
    
    
    
    if (m_control) {
        CBrCtl*   brCtl = control(m_pluginskin->frame());    
        WebView*  view = brCtl->webView();
        TPoint newPos = aEvent.CurrentPos();
        // Not sure plugins need the start position of the gesture. Not inlcuded in the new struct
        TPoint startPos = aEvent.CurrentPos();
        TPoint viewPos = view->PositionRelativeToScreen();
        TPoint ctrlPos = m_control->PositionRelativeToScreen();
        
        if (!StaticObjectsContainer::instance()->isPluginFullscreen()) {
        // adjust the position to make it relative to top left corner of 
            newPos += viewPos; 
            startPos += viewPos;
        }
        eventForPlugin.SetCurrentPos(newPos);
        eventForPlugin.SetStartPos(startPos);
        if (StaticObjectsContainer::instance()->isPluginFullscreen() ||
	    m_control->Rect().Contains(newPos - ctrlPos)) {
            NPEvent event;
            NPEventPointer ev;
            event.event = ENppEventPointer;
            ev.reserved = &eventForPlugin;
            ev.pointerEvent = NULL;
            event.param = &ev;
            ret = m_pluginskin->getNPPluginFucs()->event(m_pluginskin->getNPP(), 
                                                         static_cast<void*>(&event));
        }
    }
    else if(!m_windowedPlugin && m_pluginskin->getNPPluginFucs() && m_pluginskin->getNPPluginFucs()->event){
        TRect cliprect = m_pluginskin->getClipRect();
        TPoint newPos = aEvent.CurrentPos();
        eventForPlugin.SetCurrentPos(newPos);
        eventForPlugin.SetCurrentPos(newPos);

        if(cliprect.Contains(newPos)){
           NPEvent event;
           NPEventPointer ev;
           event.event = ENppEventPointer;
           ev.reserved = &eventForPlugin;
           ev.pointerEvent = NULL;
           event.param = &ev;
           ret = m_pluginskin->getNPPluginFucs()->event(m_pluginskin->getNPP(), 
                                                         static_cast<void*>(&event));
        }
    }    
    return ret;

}

bool PluginWin::containsPoint(WebView& view, const TPoint& pt)
{
    if (m_control) {
        if (StaticObjectsContainer::instance()->isPluginFullscreen()) {
            return true;
        }
        else {
            TPoint point = pt;
            TPoint viewPos = view.PositionRelativeToScreen();
            TPoint ctrlPos = m_control->PositionRelativeToScreen();
            point += viewPos;
            return m_control->Rect().Contains(point - ctrlPos);
        }
    }
    else 
        return false;   
}
// -----------------------------------------------------------------------------
// PluginWin::SetBitmapFromPlugin
// Plugin video is captured in CFBsBitmap and handle is passed to plugin window 
// Duplicate the bitmap handle and use it to draw while Panning or Pinch zoom
// -----------------------------------------------------------------------------
void PluginWin::SetBitmapFromPlugin(TInt aHandle)
    {
    m_PluginInvisibleOnPinchZoom = EFalse;

    if (aHandle)
        {
        if (m_pausedBitmap)
            {
            delete m_pausedBitmap;
            m_pausedBitmap = NULL;
            }
        m_pausedBitmap = new (ELeave) CFbsBitmap();
        TInt dupStatus = m_pausedBitmap->Duplicate(aHandle);
        if(dupStatus == KErrNone)
            { 
            m_pluginHasBitmap = true;
            
            
            if (IsVisible())
                   {
                   MakeVisible(false);
                   }
            //setPluginFocusL(false);
            drawBitmapToWebCoreContext();
            } 
       }
    else
        {
        if(m_pausedBitmap)
        {
            delete m_pausedBitmap;
        	m_pausedBitmap = NULL;
		}
        m_pluginHasBitmap = false;
        }
    }

void PluginWin::ClearPluginBitmap()
    {
    if(m_pausedBitmap)
        {
        delete m_pausedBitmap;
        m_pausedBitmap = NULL;
        m_pluginHasBitmap = false; //clearing plugin bitmap
        }
    }

void PluginWin::drawBitmapToWebCoreContext()
    { 
    CBrCtl* brCtl = control(m_pluginskin->frame());
    WebView* view = brCtl->webView();
    WebCoreGraphicsContext* context = view->getGraphicsContext();
    CFbsBitGc& gc = context->gc();
    TRect plWinRect(m_pluginskin->getPluginWinRect());

    TRect oldcontextrect = context->clippingRect();
    TRect clippingRect = context->clippingRect();

    // save the gc state
    TWebCoreSavedContext saved(context->save());
    
    if(plWinRect != clippingRect)
        {
        context->setClippingRect(plWinRect);
        }
    gc.DrawBitmap(plWinRect, m_pausedBitmap);
    context->restore(saved);
    }

// Notify Plugins about the change in Access Point during Upgrade / Downgrade
void PluginWin::notifyAPChange(void* ap)
{
    if (m_notifier) {
        m_notifier->NotifyL( MPluginNotifier::EAccesPointChanged, ap );
    }
}
