/**************************************************************
 * 
 * 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_sw.hxx"
#ifdef SW_DLLIMPLEMENTATION
#undef SW_DLLIMPLEMENTATION
#endif



#include "dbmgr.hxx"
#include <sfx2/app.hxx>
#include <vcl/msgbox.hxx>
#include <swwait.hxx>
#include <viewopt.hxx>

#include "wrtsh.hxx"
#include "errhdl.hxx"
#include "cmdid.h"
#include "helpid.h"
#include "envfmt.hxx"
#include "envlop.hxx"
#include "envprt.hxx"
#include "fmtcol.hxx"
#include "poolfmt.hxx"
#include "view.hxx"

#include "envlop.hrc"
#include <comphelper/processfactory.hxx>

#include <unomid.h>

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


//impl in envimg.cxx
extern SW_DLLPUBLIC String MakeSender();

// --------------------------------------------------------------------------

SwEnvPreview::SwEnvPreview(SfxTabPage* pParent, const ResId& rResID) :

	Window(pParent, rResID)

{
	SetMapMode(MapMode(MAP_PIXEL));
}

// --------------------------------------------------------------------------



SwEnvPreview::~SwEnvPreview()
{
}

// ----------------------------------------------------------------------------
void SwEnvPreview::DataChanged( const DataChangedEvent& rDCEvt )
{
	Window::DataChanged( rDCEvt );
	if ( DATACHANGED_SETTINGS == rDCEvt.GetType() )
		SetBackground( GetSettings().GetStyleSettings().GetDialogColor() );
}

// ----------------------------------------------------------------------------

void SwEnvPreview::Paint(const Rectangle &)
{
	const StyleSettings& rSettings = GetSettings().GetStyleSettings();

	const SwEnvItem& rItem =
		((SwEnvDlg*) GetParent()->GetParent()->GetParent())->aEnvItem;

	sal_uInt16 nPageW = (sal_uInt16) Max(rItem.lWidth, rItem.lHeight),
		   nPageH = (sal_uInt16) Min(rItem.lWidth, rItem.lHeight);

    float fx = (float)GetOutputSizePixel().Width () / (float)nPageW,
          fy = (float)GetOutputSizePixel().Height() / (float)nPageH,
          f  = 0.8f * ( fx < fy ? fx : fy );

	Color aBack = rSettings.GetWindowColor( );
    Color aFront = SwViewOption::GetFontColor();
	Color aMedium = Color(	( aBack.GetRed() + aFront.GetRed() ) / 2,
							( aBack.GetGreen() + aFront.GetGreen() ) / 2,
							( aBack.GetBlue() + aFront.GetBlue() ) / 2
						);

	SetLineColor( aFront );

	// Umschlag
	long   nW = (sal_uInt16) (f * nPageW),
		   nH = (sal_uInt16) (f * nPageH),
		   nX = (GetOutputSizePixel().Width () - nW) / 2,
		   nY = (GetOutputSizePixel().Height() - nH) / 2;
	SetFillColor( aBack );
	DrawRect(Rectangle(Point(nX, nY), Size(nW, nH)));

	// Absender
	if (rItem.bSend)
	{
		long   nSendX = nX + (sal_uInt16) (f * rItem.lSendFromLeft),
			   nSendY = nY + (sal_uInt16) (f * rItem.lSendFromTop ),
			   nSendW = (sal_uInt16) (f * (rItem.lAddrFromLeft - rItem.lSendFromLeft)),
			   nSendH = (sal_uInt16) (f * (rItem.lAddrFromTop  - rItem.lSendFromTop  - 566));
		SetFillColor( aMedium );

		DrawRect(Rectangle(Point(nSendX, nSendY), Size(nSendW, nSendH)));
	}

	// Empfaenger
	long   nAddrX = nX + (sal_uInt16) (f * rItem.lAddrFromLeft),
		   nAddrY = nY + (sal_uInt16) (f * rItem.lAddrFromTop ),
		   nAddrW = (sal_uInt16) (f * (nPageW - rItem.lAddrFromLeft - 566)),
		   nAddrH = (sal_uInt16) (f * (nPageH - rItem.lAddrFromTop  - 566));
	SetFillColor( aMedium );
	DrawRect(Rectangle(Point(nAddrX, nAddrY), Size(nAddrW, nAddrH)));

	// Briefmarke
	long   nStmpW = (sal_uInt16) (f * 1417 /* 2,5 cm */),
		   nStmpH = (sal_uInt16) (f * 1701 /* 3,0 cm */),
		   nStmpX = nX + nW - (sal_uInt16) (f * 566) - nStmpW,
		   nStmpY = nY + (sal_uInt16) (f * 566);

	SetFillColor( aBack );
	DrawRect(Rectangle(Point(nStmpX, nStmpY), Size(nStmpW, nStmpH)));
}

// --------------------------------------------------------------------------



SwEnvDlg::SwEnvDlg(Window* pParent, const SfxItemSet& rSet,
					SwWrtShell* pWrtSh, Printer* pPrt, sal_Bool bInsert) :

	SfxTabDialog(pParent, SW_RES(DLG_ENV), &rSet, sal_False, &aEmptyStr),
	sInsert(SW_RES(ST_INSERT)),
	sChange(SW_RES(ST_CHANGE)),
	aEnvItem((const SwEnvItem&) rSet.Get(FN_ENVELOP)),
	pSh(pWrtSh),
	pPrinter(pPrt),
	pAddresseeSet(0),
	pSenderSet(0)
{
	FreeResource();

	GetOKButton().SetText(String(SW_RES(STR_BTN_NEWDOC)));
	GetOKButton().SetHelpId(HID_ENVELOP_PRINT);
	GetOKButton().SetHelpText(aEmptyStr);	// Damit generierter Hilfetext verwendet wird
	if (GetUserButton())
	{
		GetUserButton()->SetText(bInsert ? sInsert : sChange);
		GetUserButton()->SetHelpId(HID_ENVELOP_INSERT);
	}

	AddTabPage(TP_ENV_ENV, SwEnvPage   ::Create, 0);
	AddTabPage(TP_ENV_FMT, SwEnvFmtPage::Create, 0);
	AddTabPage(TP_ENV_PRT, SwEnvPrtPage::Create, 0);
}

// --------------------------------------------------------------------------



SwEnvDlg::~SwEnvDlg()
{
	delete pAddresseeSet;
	delete pSenderSet;
}

// --------------------------------------------------------------------------



void SwEnvDlg::PageCreated(sal_uInt16 nId, SfxTabPage &rPage)
{
	if (nId == TP_ENV_PRT)
	{
		((SwEnvPrtPage*)&rPage)->SetPrt(pPrinter);
	}
}

// --------------------------------------------------------------------------

short SwEnvDlg::Ok()
{
	short nRet = SfxTabDialog::Ok();

	if (nRet == RET_OK || nRet == RET_USER)
	{
		if (pAddresseeSet)
		{
			SwTxtFmtColl* pColl = pSh->GetTxtCollFromPool(RES_POOLCOLL_JAKETADRESS);
            pColl->SetFmtAttr(*pAddresseeSet);
		}
		if (pSenderSet)
		{
			SwTxtFmtColl* pColl = pSh->GetTxtCollFromPool(RES_POOLCOLL_SENDADRESS);
            pColl->SetFmtAttr(*pSenderSet);
		}
	}

	return nRet;
}

// --------------------------------------------------------------------------



SwEnvPage::SwEnvPage(Window* pParent, const SfxItemSet& rSet) :

	SfxTabPage(pParent, SW_RES(TP_ENV_ENV), rSet),

	aAddrText      (this, SW_RES(TXT_ADDR   )),
	aAddrEdit      (this, SW_RES(EDT_ADDR   )),
	aDatabaseFT    (this, SW_RES(FT_DATABASE)),
	aDatabaseLB    (this, SW_RES(LB_DATABASE)),
	aTableFT       (this, SW_RES(FT_TABLE   )),
	aTableLB       (this, SW_RES(LB_TABLE   )),
	aInsertBT      (this, SW_RES(BTN_INSERT )),
	aDBFieldFT     (this, SW_RES(FT_DBFIELD )),
	aDBFieldLB     (this, SW_RES(LB_DBFIELD )),
	aSenderBox     (this, SW_RES(BOX_SEND   )),
	aSenderEdit    (this, SW_RES(EDT_SEND   )),
	aPreview       (this, SW_RES(WIN_PREVIEW))

{
	FreeResource();
	SetExchangeSupport();
	pSh = GetParent()->pSh;

	// Handler installieren
	aDatabaseLB    .SetSelectHdl(LINK(this, SwEnvPage, DatabaseHdl	   ));
	aTableLB       .SetSelectHdl(LINK(this, SwEnvPage, DatabaseHdl	   ));
	aInsertBT      .SetClickHdl	(LINK(this, SwEnvPage, FieldHdl		   ));
	aSenderBox	   .SetClickHdl (LINK(this, SwEnvPage, SenderHdl       ));
    aPreview.SetBorderStyle( WINDOW_BORDER_MONO );

	SwDBData aData = pSh->GetDBData();
	sActDBName = aData.sDataSource;
	sActDBName += DB_DELIM;
	sActDBName += (String)aData.sCommand;
	InitDatabaseBox();
}

// --------------------------------------------------------------------------



SwEnvPage::~SwEnvPage()
{
}

// --------------------------------------------------------------------------



IMPL_LINK( SwEnvPage, DatabaseHdl, ListBox *, pListBox )
{
	SwWait aWait( *pSh->GetView().GetDocShell(), true );

	if (pListBox == &aDatabaseLB)
    {
        sActDBName = pListBox->GetSelectEntry();
        pSh->GetNewDBMgr()->GetTableNames(&aTableLB, sActDBName);
        sActDBName += DB_DELIM;
    }
    else
        sActDBName.SetToken(1, DB_DELIM, aTableLB.GetSelectEntry());
    pSh->GetNewDBMgr()->GetColumnNames(
        &aDBFieldLB, aDatabaseLB.GetSelectEntry(), aTableLB.GetSelectEntry());
	return 0;
}

// --------------------------------------------------------------------------



IMPL_LINK( SwEnvPage, FieldHdl, Button *, EMPTYARG )
{
	String aStr ( '<' );
	aStr += aDatabaseLB.GetSelectEntry();
	aStr += '.';
//	aStr += DB_DELIM;
	aStr += aTableLB.GetSelectEntry();
	aStr += '.';
    aStr += aTableLB.GetEntryData(aTableLB.GetSelectEntryPos()) == 0 ? '0' : '1';
	aStr += '.';
//  aStr += DB_DELIM;
	aStr += aDBFieldLB.GetSelectEntry();
	aStr += '>';
	aAddrEdit.ReplaceSelected(aStr);
	Selection aSel = aAddrEdit.GetSelection();
	aAddrEdit.GrabFocus();
	aAddrEdit.SetSelection(aSel);
	return 0;
}

// --------------------------------------------------------------------------



IMPL_LINK( SwEnvPage, SenderHdl, Button *, EMPTYARG )
{
	const sal_Bool bEnable = aSenderBox.IsChecked();
	GetParent()->aEnvItem.bSend = bEnable;
	aSenderEdit.Enable(bEnable);
	if ( bEnable )
    {
		aSenderEdit.GrabFocus();
        if(!aSenderEdit.GetText().Len())
            aSenderEdit.SetText(MakeSender());
    }
	aPreview.Invalidate();
	return 0;
}

// --------------------------------------------------------------------------



void SwEnvPage::InitDatabaseBox()
{
	if (pSh->GetNewDBMgr())
	{
		aDatabaseLB.Clear();
		Sequence<OUString> aDataNames = SwNewDBMgr::GetExistingDatabaseNames();
		const OUString* pDataNames = aDataNames.getConstArray();
		for (long i = 0; i < aDataNames.getLength(); i++)
			aDatabaseLB.InsertEntry(pDataNames[i]);

		String sDBName = sActDBName.GetToken( 0, DB_DELIM );
		String sTableName = sActDBName.GetToken( 1, DB_DELIM );
		aDatabaseLB.SelectEntry(sDBName);
		if (pSh->GetNewDBMgr()->GetTableNames(&aTableLB, sDBName))
		{
			aTableLB.SelectEntry(sTableName);
            pSh->GetNewDBMgr()->GetColumnNames(&aDBFieldLB, sDBName, sTableName);
		}
		else
			aDBFieldLB.Clear();

	}
}

// --------------------------------------------------------------------------



SfxTabPage* SwEnvPage::Create(Window* pParent, const SfxItemSet& rSet)
{
	return new SwEnvPage(pParent, rSet);
}

// --------------------------------------------------------------------------



void SwEnvPage::ActivatePage(const SfxItemSet& rSet)
{
	SfxItemSet aSet(rSet);
	aSet.Put(GetParent()->aEnvItem);
	Reset(aSet);
}

// --------------------------------------------------------------------------



int SwEnvPage::DeactivatePage(SfxItemSet* _pSet)
{
	FillItem(GetParent()->aEnvItem);
    if( _pSet )
        FillItemSet(*_pSet);
	return SfxTabPage::LEAVE_PAGE;
}

// --------------------------------------------------------------------------



void SwEnvPage::FillItem(SwEnvItem& rItem)
{
	rItem.aAddrText = aAddrEdit  .GetText();
	rItem.bSend     = aSenderBox .IsChecked();
	rItem.aSendText = aSenderEdit.GetText();
}

// --------------------------------------------------------------------------



sal_Bool SwEnvPage::FillItemSet(SfxItemSet& rSet)
{
	FillItem(GetParent()->aEnvItem);
	rSet.Put(GetParent()->aEnvItem);
	return sal_True;
}

// ----------------------------------------------------------------------------



void SwEnvPage::Reset(const SfxItemSet& rSet)
{
	SwEnvItem aItem = (const SwEnvItem&) rSet.Get(FN_ENVELOP);
	aAddrEdit  .SetText(String(aItem.aAddrText).ConvertLineEnd());
	aSenderEdit.SetText(String(aItem.aSendText).ConvertLineEnd());
	aSenderBox .Check  (aItem.bSend);
	aSenderBox.GetClickHdl().Call(&aSenderBox);
}


