/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 *
 *************************************************************/



import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.IQueryInterface;
import com.sun.star.lang.XInitialization;
import com.sun.star.lang.XEventListener;
import com.sun.star.awt.*;
import com.sun.star.media.*;

// -----------------
// - Player Window -
// -----------------

public class PlayerWindow implements java.awt.event.KeyListener,
                                     java.awt.event.MouseListener,
                                     java.awt.event.MouseMotionListener,
                                     java.awt.event.FocusListener,
                                     com.sun.star.lang.XServiceInfo,
                                     com.sun.star.media.XPlayerWindow
{
    private com.sun.star.lang.XMultiServiceFactory maFactory;
    private WindowAdapter maFrame;
    private javax.media.Player maPlayer;
    private com.sun.star.media.ZoomLevel meZoomLevel = com.sun.star.media.ZoomLevel.ORIGINAL;
    private boolean mbShowControls = false;


    // -------------------------------------------------------------------------

    public PlayerWindow( com.sun.star.lang.XMultiServiceFactory aFactory,
                         java.lang.Object[] aArgs, javax.media.Player aPlayer )
    {
        maFactory = aFactory;

        try
        {
            if( aArgs.length > 1 )
            {
                com.sun.star.awt.Rectangle aBoundRect = (com.sun.star.awt.Rectangle) aArgs[ 1 ];

                maFrame = new WindowAdapter( AnyConverter.toInt( aArgs[ 0 ] ) );
                maFrame.setPosSize( aBoundRect.X, aBoundRect.Y, aBoundRect.Width, aBoundRect.Height, (short) 0 );
                mbShowControls = false;

                java.awt.Panel aPanel = new java.awt.Panel( new java.awt.BorderLayout() );

                aPanel.setLayout( null );
                aPanel.setBackground( java.awt.Color.black );
                aPanel.addKeyListener( this );
                aPanel.addMouseListener( this );
                aPanel.addMouseMotionListener( this );

                if( mbShowControls )
                {
                    java.awt.Component aControlComponent = aPlayer.getControlPanelComponent();

                    if( aControlComponent != null )
                        aPanel.add( aControlComponent );
                    else
                        mbShowControls = false;
                }

                java.awt.Component aVisualComponent = aPlayer.getVisualComponent();

                if( aVisualComponent != null )
                {
                    aVisualComponent.addKeyListener( this );
                    aVisualComponent.addMouseListener( this );
                    aVisualComponent.addMouseMotionListener( this );
                    aVisualComponent.addFocusListener( this );
                    aPanel.add( aVisualComponent );
                }
                else
                    meZoomLevel = com.sun.star.media.ZoomLevel.NOT_AVAILABLE;

                if( maFrame.getJavaFrame() != null )
                    maFrame.getJavaFrame().add( aPanel );

                LayoutComponents();
            }
        }
        catch( com.sun.star.lang.IllegalArgumentException e )
        {
        }
    }

    // -------------------------------------------------------------------------

    protected synchronized void LayoutComponents()
    {
        if( maFrame.getJavaFrame() != null )
        {
            java.awt.Panel  aPanel = (java.awt.Panel) maFrame.getJavaFrame().getComponent( 0 );
            int             nW = maFrame.getJavaFrame().getWidth();
            int             nH = maFrame.getJavaFrame().getHeight();
            int             nControlH = 0;

            aPanel.setBounds( 0, 0, nW, nH );

            if( mbShowControls )
            {
                java.awt.Component aControlComponent = aPanel.getComponent( 0 );

                if( aControlComponent != null )
                {
                    java.awt.Dimension aControlDimension = aControlComponent.getPreferredSize();

                    nControlH = Math.min( nH, aControlDimension.height );
                    aControlComponent.setBounds( 0, nH - nControlH, nW, nControlH );
                }
            }

            if( com.sun.star.media.ZoomLevel.NOT_AVAILABLE != meZoomLevel )
            {
                java.awt.Component aVisualComponent = aPanel.getComponent( mbShowControls ? 1 : 0 );

                if( aVisualComponent != null )
                {
                    java.awt.Dimension  aPrefDim = aVisualComponent.getPreferredSize();
                    int                 nVideoW = nW, nVideoH = ( nH - nControlH );
                    int                 nX = 0, nY = 0, nWidth = 0, nHeight = 0;
                    boolean             bDone = false, bZoom = false;

                    if( com.sun.star.media.ZoomLevel.ORIGINAL == meZoomLevel )
                    {
                        bZoom = true;
                    }
                    else if( com.sun.star.media.ZoomLevel.ZOOM_1_TO_4 == meZoomLevel )
                    {
                        aPrefDim.width >>= 2;
                        aPrefDim.height >>= 2;
                        bZoom = true;
                    }
                    else if( com.sun.star.media.ZoomLevel.ZOOM_1_TO_2 == meZoomLevel )
                    {
                        aPrefDim.width >>= 1;
                        aPrefDim.height >>= 1;
                        bZoom = true;
                    }
                    else if( com.sun.star.media.ZoomLevel.ZOOM_2_TO_1 == meZoomLevel )
                    {
                        aPrefDim.width <<= 1;
                        aPrefDim.height <<= 1;
                        bZoom = true;
                    }
                    else if( com.sun.star.media.ZoomLevel.ZOOM_4_TO_1 == meZoomLevel )
                    {
                        aPrefDim.width <<= 2;
                        aPrefDim.height <<= 2;
                        bZoom = true;
                    }
                    else if( com.sun.star.media.ZoomLevel.FIT_TO_WINDOW == meZoomLevel )
                    {
                        nWidth = nVideoW;
                        nHeight = nVideoH;
                        bDone = true;
                    }

                    if( bZoom )
                    {
                        if( ( aPrefDim.width <= nVideoW ) && ( aPrefDim.height <= nVideoH ) )
                        {
                            nX = ( nVideoW - aPrefDim.width ) >> 1;
                            nY = ( nVideoH - aPrefDim.height ) >> 1;
                            nWidth = aPrefDim.width;
                            nHeight = aPrefDim.height;
                            bDone = true;
                        }
                    }

                    if( !bDone )
                    {
                        if( aPrefDim.width > 0 && aPrefDim.height > 0 && nVideoW > 0 && nVideoH > 0 )
                        {
                            double fPrefWH = (double) aPrefDim.width / aPrefDim.height;

                            if( fPrefWH < ( (double) nVideoW / nVideoH ) )
                                nVideoW = (int)( nVideoH * fPrefWH );
                            else
                                nVideoH = (int)( nVideoW / fPrefWH );

                            nX = ( nW - nVideoW ) >> 1;
                            nY = ( nH - nControlH - nVideoH ) >> 1;
                            nWidth = nVideoW;
                            nHeight = nVideoH;
                        }
                        else
                            nX = nY = nWidth = nHeight = 0;
                    }

                    aVisualComponent.setBounds( nX, nY, nWidth, nHeight );
                    aVisualComponent.requestFocus();
                }
                else
                    aPanel.requestFocus();
            }
            else
                aPanel.requestFocus();
        }
    }

    // -------------------------------------------------------------------------

    private void implFireMouseEvent( java.awt.event.MouseEvent aEvt )
    {
        if( aEvt.getSource() != null &&
            aEvt.getSource() instanceof java.awt.Component )
        {
            aEvt.translatePoint( ( (java.awt.Component) aEvt.getSource() ).getX(),
                                 ( (java.awt.Component) aEvt.getSource() ).getY() );
        }

        maFrame.fireMouseEvent( aEvt );
    }

    // ---------------
    // - KeyListener -
    // ---------------

    public void keyPressed( java.awt.event.KeyEvent aEvt )
    {
        maFrame.fireKeyEvent( aEvt );
    }

    // -------------------------------------------------------------------------

    public void keyReleased( java.awt.event.KeyEvent aEvt )
    {
        maFrame.fireKeyEvent( aEvt );
    }

    // -------------------------------------------------------------------------

    public void keyTyped( java.awt.event.KeyEvent aEvt )
    {
        maFrame.fireKeyEvent( aEvt );
    }

    // -----------------
    // - MouseListener -
    // -----------------

    public void mousePressed( java.awt.event.MouseEvent aEvt )
    {
        implFireMouseEvent( aEvt );
    }

    // -------------------------------------------------------------------------

    public void mouseClicked( java.awt.event.MouseEvent aEvt )
    {
        implFireMouseEvent( aEvt );
    }

    // -------------------------------------------------------------------------

    public void mouseEntered( java.awt.event.MouseEvent aEvt )
    {
        implFireMouseEvent( aEvt );
    }

    // -------------------------------------------------------------------------

    public void mouseExited( java.awt.event.MouseEvent aEvt )
    {
        implFireMouseEvent( aEvt );
    }

    // -------------------------------------------------------------------------

    public void mouseReleased( java.awt.event.MouseEvent aEvt )
    {
        implFireMouseEvent( aEvt );
    }

    // -----------------------
    // - MouseMotionListener -
    // -----------------------

    public void mouseDragged( java.awt.event.MouseEvent aEvt )
    {
        implFireMouseEvent( aEvt );
    }

    // -------------------------------------------------------------------------

    public void mouseMoved( java.awt.event.MouseEvent aEvt )
    {
        implFireMouseEvent( aEvt );
    }

    // -----------------------
    // - FocusListener -
    // -----------------------

    public void focusGained( java.awt.event.FocusEvent aEvt )
    {
        if( maFrame.getJavaFrame() != null )
            maFrame.fireFocusEvent( aEvt );
    }

    // -------------------------------------------------------------------------

    public void focusLost( java.awt.event.FocusEvent aEvt )
    {
        if( maFrame.getJavaFrame() != null )
            maFrame.fireFocusEvent( aEvt );
    }

    // -----------------
    // - XPlayerWindow -
    // -----------------

    public synchronized void update()
    {
        if( maFrame.getJavaFrame() != null )
            maFrame.getJavaFrame().repaint();
    }

    // -------------------------------------------------------------------------

    public synchronized boolean setZoomLevel( com.sun.star.media.ZoomLevel eZoomLevel )
    {
        boolean bRet = false;

        if( com.sun.star.media.ZoomLevel.NOT_AVAILABLE != meZoomLevel &&
            com.sun.star.media.ZoomLevel.NOT_AVAILABLE != eZoomLevel )
        {
            if( eZoomLevel != meZoomLevel )
            {
                meZoomLevel = eZoomLevel;
                LayoutComponents();
            }

            bRet = true;
        }

        return bRet;
    }

    // -------------------------------------------------------------------------

    public synchronized com.sun.star.media.ZoomLevel getZoomLevel()
    {
        return meZoomLevel;
    }

    // -------------------------------------------------------------------------

    public synchronized void setPointerType( int nPointerType )
    {
        if( maFrame.getJavaFrame() != null )
        {
            int nCursor;

            switch( nPointerType )
            {
                case( com.sun.star.awt.SystemPointer.CROSS ): nCursor = java.awt.Cursor.CROSSHAIR_CURSOR; break;
                case( com.sun.star.awt.SystemPointer.HAND ): nCursor = java.awt.Cursor.HAND_CURSOR; break;
                case( com.sun.star.awt.SystemPointer.MOVE ): nCursor = java.awt.Cursor.MOVE_CURSOR; break;
                case( com.sun.star.awt.SystemPointer.WAIT ): nCursor = java.awt.Cursor.WAIT_CURSOR; break;

                default: nCursor = java.awt.Cursor.DEFAULT_CURSOR; break;
            }

            maFrame.getJavaFrame().setCursor( java.awt.Cursor.getPredefinedCursor( nCursor ) );
        }
    }

    // --------------
    // - XComponent -
    // --------------

    public synchronized void dispose()
    {
        if( maFrame != null )
        {
            java.awt.Panel aPanel = (java.awt.Panel) maFrame.getJavaFrame().getComponent( 0 );

            if( aPanel != null && aPanel.getComponent( 0 ) != null )
                aPanel.getComponent( 0 ).removeFocusListener( this );

            if( maFrame.getJavaFrame() != null )
                maFrame.getJavaFrame().dispose();

            maFrame.fireDisposingEvent();
        }

        maFrame = null;
    }

    // -----------
    // - XWindow -
    // -----------

    public synchronized void setPosSize( int X, int Y, int Width, int Height, short Flags )
    {
        if( maFrame != null )
        {
            maFrame.setPosSize( X, Y, Width, Height, Flags );
            LayoutComponents();
        }
    }

    // -------------------------------------------------------------------------

    public synchronized com.sun.star.awt.Rectangle getPosSize()
    {
        return( ( maFrame != null ) ? maFrame.getPosSize() : new com.sun.star.awt.Rectangle() );
    }

    // -------------------------------------------------------------------------

    public synchronized void setVisible( boolean visible )
    {
        if( maFrame != null )
            maFrame.setVisible( visible );
    }

    // -------------------------------------------------------------------------

    public synchronized void setEnable( boolean enable )
    {
        if( maFrame != null )
            maFrame.setEnable( enable );
    }

    // -------------------------------------------------------------------------

    public synchronized void setFocus()
    {
        if( maFrame != null )
            maFrame.setFocus();
    }

    // -------------------------------------------------------------------------

    public synchronized void addEventListener( com.sun.star.lang.XEventListener xListener )
    {
        if( maFrame != null )
            maFrame.addEventListener( xListener );
    }

    // -------------------------------------------------------------------------

    public synchronized void removeEventListener( com.sun.star.lang.XEventListener xListener )
    {
        if( maFrame != null )
            maFrame.removeEventListener( xListener );
    }

    // -------------------------------------------------------------------------

    public synchronized void addWindowListener( XWindowListener xListener )
    {
        if( maFrame != null )
            maFrame.addWindowListener( xListener );
    }

    // -------------------------------------------------------------------------

    public synchronized void removeWindowListener( XWindowListener xListener )
    {
        if( maFrame != null )
            maFrame.removeWindowListener( xListener );
    }

    // -------------------------------------------------------------------------

    public synchronized void addFocusListener( XFocusListener xListener )
    {
        if( maFrame != null )
            maFrame.addFocusListener( xListener );
    }

    // -------------------------------------------------------------------------

    public synchronized void removeFocusListener( XFocusListener xListener )
    {
        if( maFrame != null )
            maFrame.removeFocusListener( xListener );
    }

    // -------------------------------------------------------------------------

    public synchronized void addKeyListener( XKeyListener xListener )
    {
        if( maFrame != null )
            maFrame.addKeyListener( xListener );
    }

    // -------------------------------------------------------------------------

    public synchronized void removeKeyListener( XKeyListener xListener )
    {
        if( maFrame != null )
            maFrame.removeKeyListener( xListener );
    }

    // -------------------------------------------------------------------------

    public synchronized void addMouseListener( XMouseListener xListener )
    {
        if( maFrame != null )
            maFrame.addMouseListener( xListener );
    }

    // -------------------------------------------------------------------------

    public synchronized void removeMouseListener( XMouseListener xListener )
    {
        if( maFrame != null )
            maFrame.removeMouseListener( xListener );
    }

    // -------------------------------------------------------------------------

    public synchronized void addMouseMotionListener( XMouseMotionListener xListener )
    {
        if( maFrame != null )
            maFrame.addMouseMotionListener( xListener );
    }

    // -------------------------------------------------------------------------

    public synchronized void removeMouseMotionListener( XMouseMotionListener xListener )
    {
        if( maFrame != null )
            maFrame.removeMouseMotionListener( xListener );
    }

    // -------------------------------------------------------------------------

    public synchronized void addPaintListener( XPaintListener xListener )
    {
        if( maFrame != null )
            maFrame.addPaintListener( xListener );
    }

    // -------------------------------------------------------------------------

    public synchronized void removePaintListener( XPaintListener xListener )
    {
        if( maFrame != null )
            maFrame.removePaintListener( xListener );
    }

    // ----------------
    // - XServiceInfo -
    // ----------------

    private static final String s_implName = "com.sun.star.comp.PlayerWindow_Java";
    private static final String s_serviceName = "com.sun.star.media.PlayerWindow_Java";

    public synchronized String getImplementationName()
    {
        return s_implName;
    }

    // -------------------------------------------------------------------------

    public synchronized String [] getSupportedServiceNames()
    {
        return new String [] { s_serviceName };
    }

    // -------------------------------------------------------------------------

    public synchronized boolean supportsService( String serviceName )
    {
        return serviceName.equals( s_serviceName );
    }
}
