/**************************************************************
 * 
 * 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_sc.hxx"

// System - Includes -----------------------------------------------------



// INCLUDE ---------------------------------------------------------------

#include "hintwin.hxx"
#include "global.hxx"

#define HINT_LINESPACE	2
#define HINT_INDENT		3
#define HINT_MARGIN		4

//==================================================================

ScHintWindow::ScHintWindow( Window* pParent, const String& rTit, const String& rMsg ) :
	Window( pParent, WinBits( WB_BORDER ) ),
	aTitle( rTit ),
	aMessage( rMsg )
{
	aMessage.ConvertLineEnd( LINEEND_CR );

	//	Hellgelb, wie Notizen in detfunc.cxx
	Color aYellow( 255,255,192 );			// hellgelb
	SetBackground( aYellow );

	aTextFont = GetFont();
	aTextFont.SetTransparent( sal_True );
	aTextFont.SetWeight( WEIGHT_NORMAL );
	aHeadFont = aTextFont;
	aHeadFont.SetWeight( WEIGHT_BOLD );

	SetFont( aHeadFont );
	Size aHeadSize( GetTextWidth( aTitle ), GetTextHeight() );
	SetFont( aTextFont );

	Size aTextSize;
	xub_StrLen nIndex = 0;
	while ( nIndex != STRING_NOTFOUND )
	{
		String aLine = aMessage.GetToken( 0, CHAR_CR, nIndex );
		Size aLineSize( GetTextWidth( aLine ), GetTextHeight() );
		nTextHeight = aLineSize.Height();
		aTextSize.Height() += nTextHeight;
		if ( aLineSize.Width() > aTextSize.Width() )
			aTextSize.Width() = aLineSize.Width();
	}
	aTextSize.Width() += HINT_INDENT;

	aTextStart = Point( HINT_MARGIN + HINT_INDENT,
						aHeadSize.Height() + HINT_MARGIN + HINT_LINESPACE );

	Size aWinSize( Max( aHeadSize.Width(), aTextSize.Width() ) + 2 * HINT_MARGIN + 1,
					aHeadSize.Height() + aTextSize.Height() + HINT_LINESPACE + 2 * HINT_MARGIN + 1 );
	SetOutputSizePixel( aWinSize );
}


ScHintWindow::~ScHintWindow()
{
}


void __EXPORT ScHintWindow::Paint( const Rectangle& /* rRect */ )
{
	SetFont( aHeadFont );
	DrawText( Point(HINT_MARGIN,HINT_MARGIN), aTitle );

	SetFont( aTextFont );
	xub_StrLen nIndex = 0;
	Point aLineStart = aTextStart;
	while ( nIndex != STRING_NOTFOUND )
	{
		String aLine = aMessage.GetToken( 0, CHAR_CR, nIndex );
		DrawText( aLineStart, aLine );
		aLineStart.Y() += nTextHeight;
	}
}
