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

