/**************************************************************
 *
 * 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.
 *
 *************************************************************/

package embeddedobj.test;

import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;

import com.sun.star.awt.XBitmap;
import com.sun.star.awt.XDevice;
import com.sun.star.awt.XDisplayBitmap;
import com.sun.star.awt.XGraphics;
import com.sun.star.awt.XWindow;
import com.sun.star.awt.XWindowPeer;
import com.sun.star.awt.XToolkit;
import com.sun.star.awt.XSystemChildFactory;
import com.sun.star.awt.WindowDescriptor;
import com.sun.star.awt.WindowClass;
import com.sun.star.awt.WindowAttribute;

import com.sun.star.awt.XPaintListener;
import com.sun.star.awt.PaintEvent;
import com.sun.star.awt.XMouseListener;
import com.sun.star.awt.XMouseMotionListener;
import com.sun.star.awt.MouseEvent;
import com.sun.star.awt.Point;

import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.Any;
import com.sun.star.lang.XMultiServiceFactory;

import com.sun.star.task.XJob;
import com.sun.star.beans.NamedValue;


class BitmapPainter implements XPaintListener, XMouseListener, XMouseMotionListener, XJob
{
	private XWindow m_xWindow;
	private XBitmap m_xBitmap;

	private com.sun.star.awt.Rectangle m_aDrawRect;

	private Object m_oImageLock;

	private PaintThread m_aPaintThread;

	// private XJob m_xMainThreadExecutor;
	// private NamedValue[] m_pValuesForExecutor;

	private boolean m_bFree = true;

	private boolean m_bProceedWithPainting = true;

// Methods
	//------------------------------------------------------
	public BitmapPainter( XJob xJob, XWindow xWindow, XBitmap xBitmap, com.sun.star.awt.Rectangle aDrawRect )
	{
		if ( xJob == null )
		{
			System.out.println( "No mainthreadexecutor is provided to BimapPainter on init!" );
			throw new com.sun.star.uno.RuntimeException();
		}

		if ( xWindow == null )
		{
			System.out.println( "No window is provided to BimapPainter on init!" );
			throw new com.sun.star.uno.RuntimeException();
		}

		// m_xMainThreadExecutor = xJob;
		// m_pValuesForExecutor = new NamedValue[1];
		// m_pValuesForExecutor[0] = new NamedValue( "JobToExecute", (Object)this );

		m_xWindow = xWindow;
		m_xBitmap = xBitmap;

		m_aDrawRect = aDrawRect;

		m_oImageLock = new Object();

		m_aPaintThread = new PaintThread( m_xWindow );
		m_aPaintThread.start();

		m_xWindow.addPaintListener( this );
		m_xWindow.addMouseListener( this );
		m_xWindow.addMouseMotionListener( this );
	}

	//------------------------------------------------------
	public void disconnectListener()
	{
		m_aPaintThread.disposeThread();
		m_xWindow.removePaintListener( this );
		m_xWindow.removeMouseListener( this );
		m_xWindow.removeMouseMotionListener( this );
	}

	//------------------------------------------------------
	public void setBitmap( XBitmap xBitmap )
	{
		synchronized( m_oImageLock )
		{
			m_xBitmap = xBitmap;
		}
	}

	//------------------------------------------------------
	public void setPos( com.sun.star.awt.Point aPoint )
	{
		synchronized( m_oImageLock )
		{
			m_aDrawRect.X = aPoint.X;
			m_aDrawRect.Y = aPoint.Y;
		}
	}

	//------------------------------------------------------
	public void setRect( com.sun.star.awt.Rectangle aRect )
	{
		synchronized( m_oImageLock )
		{
			m_aDrawRect = aRect;
		}
	}

	//------------------------------------------------------
	public void setSize( com.sun.star.awt.Size aSize )
	{
		synchronized( m_oImageLock )
		{
			m_aDrawRect.Width = aSize.Width;
			m_aDrawRect.Height = aSize.Height;
		}
	}

	//------------------------------------------------------
	public void stopPainting()
	{
		m_bProceedWithPainting = false;
	}

	//------------------------------------------------------
	public void startPainting()
	{
		m_bProceedWithPainting = true;
	}

	// XPaintListener
	//------------------------------------------------------
	public void windowPaint( PaintEvent e )
	{
		if ( !m_bProceedWithPainting )
			return;

		XBitmap xBitmap = null;
		com.sun.star.awt.Rectangle aRect = null;
		// boolean bFree = false;

		synchronized( m_oImageLock )
		{
			xBitmap = m_xBitmap;
			aRect = m_aDrawRect;
			// if ( m_bFree )
			// {
				// bFree = true;
				// m_bFree = false;
			// }
		}

		m_aPaintThread.setPaintRequest( xBitmap, aRect, e.UpdateRect );
		// if ( bFree )
		// {
			// try {
				// m_xMainThreadExecutor.execute( m_pValuesForExecutor );
			// } catch( Exception ex )
			// {
				// m_bFree = true;
			// }
		// }

		System.out.println( "VCL window paint event!" );
	}

	// XMouseListener
	//------------------------------------------------------
	public void mousePressed( MouseEvent e )
	{
	}

	//------------------------------------------------------
	public void mouseReleased( MouseEvent e )
	{
	}

	//------------------------------------------------------
	public void mouseEntered( MouseEvent e )
	{
	}

	//------------------------------------------------------
	public void mouseExited( MouseEvent e )
	{
	}

	// XMouseMotionListener
	//------------------------------------------------------
	public void mouseDragged( MouseEvent e )
	{
		// TODO: react to resizing of object bitmap
		// if the object is inplace active the object must control resizing
	}

	//------------------------------------------------------
	public void mouseMoved( MouseEvent e )
	{

	}

	// XEventListener
	//------------------------------------------------------
	public void disposing( com.sun.star.lang.EventObject e )
	{
		// do nothing, the window can die only when the application is closed
	}

	// XJob
	//------------------------------------------------------
	public Object execute( NamedValue[] pValues )
	{
/*
		// means request for painting

		XBitmap xBitmap = null;
		com.sun.star.awt.Rectangle aRect = null;

		synchronized( m_oImageLock )
		{
			xBitmap = m_xBitmap;
			aRect = m_aDrawRect;
		}

		System.out.println( "The bitmap is going to be painted!" );

		try {
			XDevice xDevice = (XDevice)UnoRuntime.queryInterface( XDevice.class, m_xWindow );
			if ( xDevice != null )
			{
				System.out.println( "Step1" );
				XGraphics xGraphics = xDevice.createGraphics();
				if ( xBitmap != null )
				{
					System.out.println( "Step2" );
					XDisplayBitmap xDisplayBitmap = xDevice.createDisplayBitmap( xBitmap );

					com.sun.star.awt.Size aSize = xBitmap.getSize();
					xGraphics.draw( xDisplayBitmap, 0, 0, aSize.Width, aSize.Height,
												aRect.X, aRect.Y, aRect.Width, aRect.Height );
				}

				System.out.println( "Step3" );
				xGraphics.drawRect( aRect.X - 1, aRect.Y - 1, aRect.Width + 2, aRect.Height + 2 );

				// draw resize squares
				System.out.println( "Step4" );
				xGraphics.drawRect( aRect.X - 2, aRect.Y - 2, 4, 4 );
				xGraphics.drawRect( aRect.X + aRect.Width - 2, aRect.Y - 2, 4, 4 );
				xGraphics.drawRect( aRect.X - 2, aRect.Y + aRect.Height - 2, 4, 4 );
				xGraphics.drawRect( aRect.X + aRect.Width - 2, aRect.Y + aRect.Height - 2, 4, 4 );

				System.out.println( "Step5" );

				System.out.println( "The bitmap is painted by BitmapPainter!" );
			}
		}
		catch ( Exception e )
		{
		}

		m_bFree = true;

*/
		return Any.VOID;
	}

};
