/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sd_sdwindow.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2006/10/27 18:47:09 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/


#include "app.hrc"
#include "helpids.h"
#include "sdwindow.hxx"
#include "drviewsh.hxx"

namespace binfilter {


#define SCROLL_LINE_FACT   0.05     // Faktor fuer Zeilenscrolling
#define SCROLL_PAGE_FACT   0.5      // Faktor fuer Seitenscrolling
#define SCROLL_SENSITIVE   20       // Sensitiver Bereich (Pixel)
#define ZOOM_MULTIPLICATOR 10000    // Multiplikator um Rundungsfehler zu vermeiden
#define MIN_ZOOM	       5        // Minimaler Zoomfaktor
#define MAX_ZOOM	       3000	    // Maximaler Zoomfaktor


/*************************************************************************
|*
|* Konstruktor
|*
\************************************************************************/

/*N*/ SdWindow::SdWindow(Window* pParent) :
/*N*/ 	Window(pParent, WinBits(WB_CLIPCHILDREN | WB_DIALOGCONTROL)),
/*N*/ 	DropTargetHelper( this ),
/*N*/ 	pShareWin(NULL),
/*N*/ 	pViewShell(NULL),
/*N*/ 	aWinPos(0, 0),			// vorsichtshalber; die Werte sollten aber
/*N*/ 	aViewOrigin(0, 0),		// vom Besitzer des Fensters neu gesetzt
/*N*/ 	aViewSize(1000, 1000),	// werden
/*N*/ 	nMinZoom(MIN_ZOOM),
/*N*/ 	nMaxZoom(MAX_ZOOM),
/*N*/ 	bMinZoomAutoCalc(FALSE),
/*N*/ 	bCalcMinZoomByMinSide(TRUE),
/*N*/ 	bCenterAllowed(TRUE),
/*N*/ 	nTicks (0)
/*N*/ {
/*N*/ 	SetDialogControlFlags( WINDOW_DLGCTRL_RETURN | WINDOW_DLGCTRL_WANTFOCUS );
/*N*/ 
/*N*/ 	MapMode aMap(GetMapMode());
/*N*/ 	aMap.SetMapUnit(MAP_100TH_MM);
/*N*/ 	SetMapMode(aMap);
/*N*/ 
/*N*/ 	// Damit im Diamodus die WindowColor genommen wird
/*N*/ 	SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetWindowColor() ) );
/*N*/ 
/*N*/ 	// adjust contrast mode initially
/*N*/ 	bool bUseContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
/*N*/     SetDrawMode( bUseContrast ? OUTPUT_DRAWMODE_CONTRAST : OUTPUT_DRAWMODE_COLOR );
/*N*/ 
/*N*/ 	// Hilfe-ID setzen
/*N*/ 	// SetHelpId(HID_SD_WIN_DOCUMENT);
/*N*/ 	SetUniqueId(HID_SD_WIN_DOCUMENT);
/*N*/ }

/*************************************************************************
|*
|* Destruktor
|*
\************************************************************************/

/*N*/ SdWindow::~SdWindow()
/*N*/ {
/*N*/     if (pViewShell != NULL)
/*N*/     {
/*?*/         DBG_BF_ASSERT(0, "STRIP"); //STRIP001 ::binfilter::bifilter::sd::WindowUpdater* pWindowUpdater = pViewShell->GetWindowUpdater();
/*N*/     }
/*N*/ }

/*N*/ void SdWindow::SetViewShell(SdViewShell* pViewSh) 
/*N*/ {
/*N*/     ::binfilter::sd::WindowUpdater* pWindowUpdater = NULL;
/*N*/     // Unregister at device updater of old view shell.
/*N*/     if (pViewShell != NULL)
/*N*/     {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*N*/     }
/*N*/ 
/*N*/     pViewShell = pViewSh;
/*N*/ 
/*N*/     // Register at device updater of new view shell
/*N*/     if (pViewShell != NULL)
/*N*/     {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 
/*N*/     }
/*N*/ }


/*N*/ void SdWindow::CalcMinZoom()
/*N*/ {
/*N*/     // Are we entitled to change the minimal zoom factor?
/*N*/ 	if ( bMinZoomAutoCalc )
/*N*/ 	{
/*N*/         // Get current zoom factor.
/*N*/ 		long nZoom = GetZoom();
/*N*/ 
/*N*/ 		if ( pShareWin )
/*N*/ 		{
/*?*/ 			pShareWin->CalcMinZoom();
/*?*/ 			nMinZoom = pShareWin->nMinZoom;
/*?*/ 		}
/*N*/ 		else
/*N*/ 		{
/*N*/             // Get the rectangle of the output area in logical coordinates
/*N*/             // and calculate the scaling factors that would lead to the view
/*N*/             // area (also called application area) to completely fill the
/*N*/             // window.
/*N*/ 			Size aWinSize = PixelToLogic(GetOutputSizePixel());
/*N*/ 			ULONG nX = (ULONG) ((double) aWinSize.Width()  
/*N*/                 * (double) ZOOM_MULTIPLICATOR / (double) aViewSize.Width());
/*N*/ 			ULONG nY = (ULONG) ((double) aWinSize.Height() 
/*N*/                 * (double) ZOOM_MULTIPLICATOR / (double) aViewSize.Height());
/*N*/ 
/*N*/             // Decide whether to take the larger or the smaller factor.
/*N*/ 			ULONG nFact;
/*N*/ 			if ( bCalcMinZoomByMinSide )	nFact = Min(nX, nY);
/*N*/ 			else							nFact = Max(nX, nY);
/*N*/ 
/*N*/             // The factor is tansfomed according to the current zoom factor.
/*N*/ 			nFact = nFact * nZoom / ZOOM_MULTIPLICATOR;
/*N*/ 			nMinZoom = Max((USHORT) MIN_ZOOM, (USHORT) nFact);
/*N*/ 		}
/*N*/         // If the current zoom factor is smaller than the calculated minimal
/*N*/         // zoom factor then set the new minimal factor as the current zoom
/*N*/         // factor.
/*N*/  		if ( nZoom < (long) nMinZoom )
/*?*/ 			DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SetZoomFactor(nMinZoom);
/*N*/ 	}
/*N*/ }

/*************************************************************************
|*
|* Resize event
|*
\************************************************************************/

/*N*/ void SdWindow::Resize()
/*N*/ {
/*N*/ 	Window::Resize();
/*N*/ 	CalcMinZoom();
/*N*/ }

/*************************************************************************
|*
|* Position der linken oberen Ecke des im Fenster sichtbaren Bereichs
|* setzen
|*
\************************************************************************/

/*N*/ void SdWindow::SetWinViewPos(const Point& rPnt)
/*N*/ {
/*N*/ 	aWinPos = rPnt;
/*N*/ }

/*************************************************************************
|*
|* Ursprung der Darstellung in Bezug zur gesamten Arbeitsflaeche setzen
|*
\************************************************************************/

/*N*/ void SdWindow::SetViewOrigin(const Point& rPnt)
/*N*/ {
/*N*/ 	aViewOrigin = rPnt;
/*N*/ }

/*************************************************************************
|*
|* Groesse der gesamten Arbeitsflaeche, die mit dem Fenster betrachtet
|* werden kann, setzen
|*
\************************************************************************/

/*N*/ void SdWindow::SetViewSize(const Size& rSize)
/*N*/ {
/*N*/ 	aViewSize = rSize;
/*N*/ 	CalcMinZoom();
/*N*/ }

/*************************************************************************
|*
|* Neuen MapMode-Origin berechnen und setzen; wenn aWinPos.X()/Y()
|* gleich -1 ist, wird die entsprechende Position zentriert
|* (z.B. fuer Initialisierung)
|*
\************************************************************************/

/*N*/ void SdWindow::UpdateMapOrigin(BOOL bInvalidate)
/*N*/ {
/*N*/ 	MapMode aMap(GetMapMode());
/*N*/ 	Point	aNewOrigin;
/*N*/ 	BOOL	bChanged = FALSE;
/*N*/ 	Size	aWinSize = PixelToLogic(GetOutputSizePixel());
/*N*/ 
/*N*/ 	if ( bCenterAllowed )
/*N*/ 	{
/*N*/ 		if ( aWinPos.X() > aViewSize.Width() - aWinSize.Width() )
/*N*/ 		{
/*N*/ 			aWinPos.X() = aViewSize.Width() - aWinSize.Width();
/*N*/ 			bChanged = TRUE;
/*N*/ 		}
/*N*/ 		if ( aWinPos.Y() > aViewSize.Height() - aWinSize.Height() )
/*N*/ 		{
/*N*/ 			aWinPos.Y() = aViewSize.Height() - aWinSize.Height();
/*N*/ 			bChanged = TRUE;
/*N*/ 		}
/*N*/ 		if ( aWinSize.Width() > aViewSize.Width() || aWinPos.X() < 0 )
/*N*/ 		{
/*N*/ 			aWinPos.X() = aViewSize.Width()  / 2 - aWinSize.Width()  / 2;
/*N*/ 			bChanged = TRUE;
/*N*/ 		}
/*N*/ 		if ( aWinSize.Height() > aViewSize.Height() || aWinPos.Y() < 0 )
/*N*/ 		{
/*N*/ 			aWinPos.Y() = aViewSize.Height() / 2 - aWinSize.Height() / 2;
/*N*/ 			bChanged = TRUE;
/*N*/ 		}
/*N*/ 		aWinPos -= aViewOrigin;
/*N*/ 		Size aPix(aWinPos.X(), aWinPos.Y());
/*N*/ 		aPix = LogicToPixel(aPix);
/*N*/ 		// Groesse muss vielfaches von BRUSH_SIZE sein, damit Muster
/*N*/ 		// richtig dargestellt werden
		// #i2237#
		// removed old stuff here which still forced zoom to be
		// %BRUSH_SIZE which is outdated now
/*N*/ 
/*N*/ 		if (pViewShell && pViewShell->ISA(SdDrawViewShell))
/*N*/ 		{
/*N*/ 			Size aViewSizePixel = LogicToPixel(aViewSize);
/*N*/ 			Size aWinSizePixel = LogicToPixel(aWinSize);
/*N*/ 
/*N*/ 			// Seite soll nicht am Fensterrand "kleben"
/*N*/ 			if (aPix.Width() == 0)
/*N*/ 			{
/*N*/ 				// #i2237#
/*N*/ 				// Since BRUSH_SIZE alignment is outdated now, i use the
/*N*/ 				// former constant here directly
/*N*/ 				aPix.Width() -= 8;
/*N*/ 			}
/*N*/ 			if (aPix.Height() == 0)
/*N*/ 			{
/*N*/ 				// #i2237#
/*N*/ 				// Since BRUSH_SIZE alignment is outdated now, i use the
/*N*/ 				// former constant here directly
/*N*/ 				aPix.Height() -= 8;
/*N*/ 			}
/*N*/ 		}
/*N*/ 
/*N*/ 		aPix = PixelToLogic(aPix);
/*N*/ 		aWinPos.X() = aPix.Width();
/*N*/ 		aWinPos.Y() = aPix.Height();
/*N*/ 		aNewOrigin.X() = - aWinPos.X();
/*N*/ 		aNewOrigin.Y() = - aWinPos.Y();
/*N*/ 		aWinPos += aViewOrigin;
/*N*/ 
/*N*/ 		aMap.SetOrigin(aNewOrigin);
/*N*/ 		SetMapMode(aMap);
/*N*/ 
/*N*/ 		if ( bChanged && bInvalidate )
/*N*/ 			Invalidate();
/*N*/ 	}
/*N*/ }

/*************************************************************************
|*
|* X-Position des sichtbaren Bereichs als Bruchteil (< 1)
|* der gesamten Arbeitsbereichbreite zuruegeben
|*
\************************************************************************/

/*N*/ double SdWindow::GetVisibleX()
/*N*/ {
/*N*/ 	return ((double) aWinPos.X() / aViewSize.Width());
/*N*/ }

/*************************************************************************
|*
|* Y-Position des sichtbaren Bereichs als Bruchteil (< 1)
|* der gesamten Arbeitsbereichhoehe zuruegeben
|*
\************************************************************************/

/*N*/ double SdWindow::GetVisibleY()
/*N*/ {
/*N*/ 	return ((double) aWinPos.Y() / aViewSize.Height());
/*N*/ }

/*************************************************************************
|*
|* X- und Y-Position des sichtbaren Bereichs als Bruchteile (< 1)
|* der gesamten Arbeitsbereichgroesse setzen
|* negative Werte werden ignoriert
|*
\************************************************************************/


/*************************************************************************
|*
|* Breite des sichtbaren Bereichs im Verhaeltnis zur
|* gesamten Arbeitsbereichbreite zuruegeben
|*
\************************************************************************/

/*N*/ double SdWindow::GetVisibleWidth()
/*N*/ {
/*N*/ 	Size aWinSize = PixelToLogic(GetOutputSizePixel());
/*N*/ 	if ( aWinSize.Width() > aViewSize.Width() )
/*N*/ 		aWinSize.Width() = aViewSize.Width();
/*N*/ 	return ((double) aWinSize.Width() / aViewSize.Width());
/*N*/ }

/*************************************************************************
|*
|* Hoehe des sichtbaren Bereichs im Verhaeltnis zur
|* gesamten Arbeitsbereichhoehe zuruegeben
|*
\************************************************************************/

/*N*/ double SdWindow::GetVisibleHeight()
/*N*/ {
/*N*/ 	Size aWinSize = PixelToLogic(GetOutputSizePixel());
/*N*/ 	if ( aWinSize.Height() > aViewSize.Height() )
/*N*/ 		aWinSize.Height() = aViewSize.Height();
/*N*/ 	return ((double) aWinSize.Height() / aViewSize.Height());
/*N*/ }

/*************************************************************************
|*
|* Breite einer Scrollspalte im Verhaeltnis zur gesamten
|* Arbeitsbereichbreite zuruegeben
|*
\************************************************************************/

/*N*/ double SdWindow::GetScrlLineWidth()
/*N*/ {
/*N*/ 	return (GetVisibleWidth() * SCROLL_LINE_FACT);
/*N*/ }

/*************************************************************************
|*
|* Breite einer Scrollspalte im Verhaeltnis zur gesamten
|* Arbeitsbereichhoehe zuruegeben
|*
\************************************************************************/

/*N*/ double SdWindow::GetScrlLineHeight()
/*N*/ {
/*N*/ 	return (GetVisibleHeight() * SCROLL_LINE_FACT);
/*N*/ }

/*************************************************************************
|*
|* Breite einer Scrollpage im Verhaeltnis zur gesamten
|* Arbeitsbereichbreite zuruegeben
|*
\************************************************************************/

/*N*/ double SdWindow::GetScrlPageWidth()
/*N*/ {
/*N*/ 	return (GetVisibleWidth() * SCROLL_PAGE_FACT);
/*N*/ }

/*************************************************************************
|*
|* Breite einer Scrollpage im Verhaeltnis zur gesamten
|* Arbeitsbereichhoehe zuruegeben
|*
\************************************************************************/

/*N*/ double SdWindow::GetScrlPageHeight()
/*N*/ {
/*N*/ 	return (GetVisibleHeight() * SCROLL_PAGE_FACT);
/*N*/ }

/*************************************************************************
|*
|* Fenster deaktivieren
|*
\************************************************************************/

/*N*/ void SdWindow::LoseFocus()
/*N*/ {
/*N*/ 	nTicks = 0;
/*N*/ 		Window::LoseFocus ();
/*N*/ }

}
