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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"
#include <svtools/helpagentwindow.hxx>
#include <osl/diagnose.h>
#include <vcl/button.hxx>
#include <vcl/bitmap.hxx>
#include <svtools/svtdata.hxx>
#include <svtools/svtools.hrc>
#include <svtools/helpid.hrc>

#define WB_AGENT_STYLE	0

//........................................................................
namespace svt
{
//........................................................................

	using namespace ::com::sun::star::uno;
	using namespace ::com::sun::star::lang;

	//====================================================================
	//= CloserButton_Impl
	//= overload of ImageButton, because sometimes vcl doesn't call the click handler
	//====================================================================
	//--------------------------------------------------------------------
	class CloserButton_Impl : public ImageButton
	{
	public:
		CloserButton_Impl( Window* pParent, WinBits nBits ) : ImageButton( pParent, nBits ) {}

		virtual void		MouseButtonUp( const MouseEvent& rMEvt );
	};

	//--------------------------------------------------------------------
	void CloserButton_Impl::MouseButtonUp( const MouseEvent& rMEvt )
	{
		ImageButton::MouseButtonUp( rMEvt );
		GetClickHdl().Call( this );
	}

	//====================================================================
	//= HelpAgentWindow
	//====================================================================
	//--------------------------------------------------------------------
	HelpAgentWindow::HelpAgentWindow( Window* _pParent )
		:FloatingWindow( _pParent, WB_AGENT_STYLE)
		,m_pCloser(NULL)
		,m_pCallback(NULL)
	{
		// -----------------
		// the closer button
		Bitmap aCloserBitmap(SvtResId(BMP_HELP_AGENT_CLOSER));
		Image aCloserImage( aCloserBitmap, Color(COL_BLACK) );
		m_pCloser = new CloserButton_Impl( this, WB_NOTABSTOP | WB_NOPOINTERFOCUS );
		static_cast<CloserButton_Impl*>(m_pCloser)->SetModeImage( aCloserImage );
		static_cast<CloserButton_Impl*>(m_pCloser)->SetClickHdl( LINK(this, HelpAgentWindow, OnButtonClicked) );
		m_pCloser->SetSizePixel( implOptimalButtonSize(aCloserImage) );
		m_pCloser->Show();
		m_pCloser->SetZOrder( NULL, WINDOW_ZORDER_LAST );

		// ----------------------------
		// calculate our preferred size
		Bitmap aHelpAgentBitmap(SvtResId(BMP_HELP_AGENT_IMAGE));
		m_aPicture = Image( aHelpAgentBitmap );
		m_aPreferredSize = m_aPicture.GetSizePixel();
		m_aPreferredSize.Width() += 2;
		m_aPreferredSize.Height() += 2;

		Size aSize = GetSizePixel();
		Size aOutputSize = GetOutputSizePixel();
		m_aPreferredSize.Width() += aSize.Width() - aOutputSize.Width();
		m_aPreferredSize.Height() += aSize.Height() - aOutputSize.Height();

		SetPointer(Pointer(POINTER_REFHAND));
		AlwaysEnableInput( sal_True, sal_True );

		// unique id for the testtool
		SetUniqueId( HID_HELPAGENT_WINDOW );
	}

	//--------------------------------------------------------------------
	HelpAgentWindow::~HelpAgentWindow()
	{
		if (m_pCloser && m_pCloser->IsTracking())
			m_pCloser->EndTracking();
		if (m_pCloser && m_pCloser->IsMouseCaptured())
			m_pCloser->ReleaseMouse();

		delete m_pCloser;
	}

	//--------------------------------------------------------------------
	void HelpAgentWindow::Paint( const Rectangle& rRect )
	{
		FloatingWindow::Paint(rRect);

		Size		aOutputSize( GetOutputSizePixel() );
		Point		aPoint=Point();
		Rectangle	aOutputRect( aPoint, aOutputSize );
		Rectangle	aInnerRect( aOutputRect );

		// paint the background
		SetLineColor( GetSettings().GetStyleSettings().GetFaceColor() );
		SetFillColor( GetSettings().GetStyleSettings().GetFaceColor() );
		DrawRect( aOutputRect );

		// paint the image
		Size aPictureSize( m_aPicture.GetSizePixel() );
		Point aPicturePos(
			aOutputRect.Left() + (aInnerRect.GetWidth() - aPictureSize.Width()) / 2,
			aOutputRect.Top() + (aInnerRect.GetHeight() - aPictureSize.Height()) / 2 );

		DrawImage( aPicturePos, m_aPicture, 0 );
	}

	//--------------------------------------------------------------------
	void HelpAgentWindow::MouseButtonUp( const MouseEvent& rMEvt )
	{
		FloatingWindow::MouseButtonUp(rMEvt);

		if (m_pCallback)
			m_pCallback->helpRequested();
	}

	//--------------------------------------------------------------------
	Size HelpAgentWindow::implOptimalButtonSize( const Image& _rButtonImage )
	{
		Size aPreferredSize = _rButtonImage.GetSizePixel();
		// add a small frame, needed by the button
		aPreferredSize.Width() += 8;
		aPreferredSize.Height() += 8;
		return aPreferredSize;
	}

	//--------------------------------------------------------------------
	void HelpAgentWindow::Resize()
	{
		FloatingWindow::Resize();

		Size aOutputSize = GetOutputSizePixel();
		Size aCloserSize = m_pCloser->GetSizePixel();
		if (m_pCloser)
			m_pCloser->SetPosPixel( Point(aOutputSize.Width() - aCloserSize.Width() - 2, 2) );
	}

	//--------------------------------------------------------------------
	IMPL_LINK( HelpAgentWindow, OnButtonClicked, Window*, _pWhichOne )
	{
		if (m_pCloser == _pWhichOne)
			if (m_pCallback)
				m_pCallback->closeAgent();
		return 0L;
	}

//........................................................................
}	// namespace svt

/* vim: set noet sw=4 ts=4: */
