/**************************************************************
 *
 * 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_basic.hxx"
#include <vcl/wrkwin.hxx>
#include <vcl/svapp.hxx>
#include <svtools/transfer.hxx>
#include "runtime.hxx"
#include <basic/sbstdobj.hxx>

#define ATTR_IMP_TYPE			1
#define ATTR_IMP_WIDTH			2
#define ATTR_IMP_HEIGHT			3
#define ATTR_IMP_BOLD			4
#define ATTR_IMP_ITALIC			5
#define ATTR_IMP_STRIKETHROUGH	6
#define ATTR_IMP_UNDERLINE		7
#define ATTR_IMP_WEIGHT			8
#define ATTR_IMP_SIZE			9
#define ATTR_IMP_NAME			10

#define METH_CLEAR				20
#define METH_GETDATA			21
#define METH_GETFORMAT			22
#define METH_GETTEXT			23
#define METH_SETDATA			24
#define METH_SETTEXT			25

//------------------------------------------------------------------------------
SbStdFactory::SbStdFactory()
{
}

SbxObject* SbStdFactory::CreateObject( const String& rClassName )
{
	if( rClassName.EqualsIgnoreCaseAscii( String( RTL_CONSTASCII_USTRINGPARAM("Picture") ) ) )
		return new SbStdPicture;
	else
		if( rClassName.EqualsIgnoreCaseAscii( String( RTL_CONSTASCII_USTRINGPARAM("Font") ) ) )
		return new SbStdFont;
	else
		return NULL;
}

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



void SbStdPicture::PropType( SbxVariable* pVar, SbxArray*, sal_Bool bWrite )
{
	if( bWrite )
	{
		StarBASIC::Error( SbERR_PROP_READONLY );
		return;
	}

	GraphicType eType = aGraphic.GetType();
	sal_Int16 nType = 0;

	if( eType == GRAPHIC_BITMAP )
		nType = 1;
	else
	if( eType != GRAPHIC_NONE )
		nType = 2;

	pVar->PutInteger( nType );
}


void SbStdPicture::PropWidth( SbxVariable* pVar, SbxArray*, sal_Bool bWrite )
{
	if( bWrite )
	{
		StarBASIC::Error( SbERR_PROP_READONLY );
		return;
	}

	Size aSize = aGraphic.GetPrefSize();
	aSize =	GetpApp()->GetAppWindow()->LogicToPixel( aSize, aGraphic.GetPrefMapMode() );
	aSize = GetpApp()->GetAppWindow()->PixelToLogic( aSize, MapMode( MAP_TWIP ) );

	pVar->PutInteger( (sal_Int16)aSize.Width() );
}

void SbStdPicture::PropHeight( SbxVariable* pVar, SbxArray*, sal_Bool bWrite )
{
	if( bWrite )
	{
		StarBASIC::Error( SbERR_PROP_READONLY );
		return;
	}

	Size aSize = aGraphic.GetPrefSize();
	aSize =	GetpApp()->GetAppWindow()->LogicToPixel( aSize, aGraphic.GetPrefMapMode() );
	aSize = GetpApp()->GetAppWindow()->PixelToLogic( aSize, MapMode( MAP_TWIP ) );

	pVar->PutInteger( (sal_Int16)aSize.Height() );
}


TYPEINIT1( SbStdPicture, SbxObject );

SbStdPicture::SbStdPicture() :
	SbxObject( String( RTL_CONSTASCII_USTRINGPARAM("Picture") ) )
{
	// Properties
	SbxVariable* p = Make( String( RTL_CONSTASCII_USTRINGPARAM("Type") ), SbxCLASS_PROPERTY, SbxVARIANT );
	p->SetFlags( SBX_READ | SBX_DONTSTORE );
	p->SetUserData( ATTR_IMP_TYPE );
	p = Make( String( RTL_CONSTASCII_USTRINGPARAM("Width") ), SbxCLASS_PROPERTY, SbxVARIANT );
	p->SetFlags( SBX_READ | SBX_DONTSTORE );
	p->SetUserData( ATTR_IMP_WIDTH );
	p = Make( String( RTL_CONSTASCII_USTRINGPARAM("Height") ), SbxCLASS_PROPERTY, SbxVARIANT );
	p->SetFlags( SBX_READ | SBX_DONTSTORE );
	p->SetUserData( ATTR_IMP_HEIGHT );
}

SbStdPicture::~SbStdPicture()
{
}


SbxVariable* SbStdPicture::Find( const String& rName, SbxClassType t )
{
	// Bereits eingetragen?
	return SbxObject::Find( rName, t );
}



void SbStdPicture::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
							   const SfxHint& rHint, const TypeId& rHintType )

{
	const SbxHint* pHint = PTR_CAST( SbxHint, &rHint );

	if( pHint )
	{
		if( pHint->GetId() == SBX_HINT_INFOWANTED )
		{
			SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
			return;
		}

		SbxVariable* pVar 	= pHint->GetVar();
		SbxArray*    pPar_ 	= pVar->GetParameters();
		sal_uInt16       nWhich	= (sal_uInt16)pVar->GetUserData();
		sal_Bool		 bWrite = pHint->GetId() == SBX_HINT_DATACHANGED;

		// Propteries
		switch( nWhich )
		{
			case ATTR_IMP_TYPE:		PropType( pVar, pPar_, bWrite ); return;
			case ATTR_IMP_WIDTH:	PropWidth( pVar, pPar_, bWrite ); return;
			case ATTR_IMP_HEIGHT:	PropHeight( pVar, pPar_, bWrite ); return;
		}

		SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
	}
}

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

void SbStdFont::PropBold( SbxVariable* pVar, SbxArray*, sal_Bool bWrite )
{
	if( bWrite )
		SetBold( pVar->GetBool() );
	else
		pVar->PutBool( IsBold() );
}

void SbStdFont::PropItalic( SbxVariable* pVar, SbxArray*, sal_Bool bWrite )
{
	if( bWrite )
		SetItalic( pVar->GetBool() );
	else
		pVar->PutBool( IsItalic() );
}

void SbStdFont::PropStrikeThrough( SbxVariable* pVar, SbxArray*, sal_Bool bWrite )
{
	if( bWrite )
		SetStrikeThrough( pVar->GetBool() );
	else
		pVar->PutBool( IsStrikeThrough() );
}

void SbStdFont::PropUnderline( SbxVariable* pVar, SbxArray*, sal_Bool bWrite )
{
	if( bWrite )
		SetUnderline( pVar->GetBool() );
	else
		pVar->PutBool( IsUnderline() );
}

void SbStdFont::PropSize( SbxVariable* pVar, SbxArray*, sal_Bool bWrite )
{
	if( bWrite )
		SetSize( (sal_uInt16)pVar->GetInteger() );
	else
		pVar->PutInteger( (sal_Int16)GetSize() );
}

void SbStdFont::PropName( SbxVariable* pVar, SbxArray*, sal_Bool bWrite )
{
	if( bWrite )
		SetFontName( pVar->GetString() );
	else
		pVar->PutString( GetFontName() );
}


TYPEINIT1( SbStdFont, SbxObject );

SbStdFont::SbStdFont() :
	SbxObject( String( RTL_CONSTASCII_USTRINGPARAM("Font") ) )
{
	// Properties
	SbxVariable* p = Make( String( RTL_CONSTASCII_USTRINGPARAM("Bold") ), SbxCLASS_PROPERTY, SbxVARIANT );
	p->SetFlags( SBX_READWRITE | SBX_DONTSTORE );
	p->SetUserData( ATTR_IMP_BOLD );
	p = Make( String( RTL_CONSTASCII_USTRINGPARAM("Italic") ), SbxCLASS_PROPERTY, SbxVARIANT );
	p->SetFlags( SBX_READWRITE | SBX_DONTSTORE );
	p->SetUserData( ATTR_IMP_ITALIC );
	p = Make( String( RTL_CONSTASCII_USTRINGPARAM("StrikeThrough") ), SbxCLASS_PROPERTY, SbxVARIANT );
	p->SetFlags( SBX_READWRITE | SBX_DONTSTORE );
	p->SetUserData( ATTR_IMP_STRIKETHROUGH );
	p = Make( String( RTL_CONSTASCII_USTRINGPARAM("Underline") ), SbxCLASS_PROPERTY, SbxVARIANT );
	p->SetFlags( SBX_READWRITE | SBX_DONTSTORE );
	p->SetUserData( ATTR_IMP_UNDERLINE );
	p = Make( String( RTL_CONSTASCII_USTRINGPARAM("Size") ), SbxCLASS_PROPERTY, SbxVARIANT );
	p->SetFlags( SBX_READWRITE | SBX_DONTSTORE );
	p->SetUserData( ATTR_IMP_SIZE );

	// Name Property selbst verarbeiten
	p = Find( String( RTL_CONSTASCII_USTRINGPARAM("Name") ), SbxCLASS_PROPERTY );
	DBG_ASSERT( p, "Keine Name Property" );
	p->SetUserData( ATTR_IMP_NAME );
}

SbStdFont::~SbStdFont()
{
}


SbxVariable* SbStdFont::Find( const String& rName, SbxClassType t )
{
	// Bereits eingetragen?
	return SbxObject::Find( rName, t );
}



void SbStdFont::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
							const SfxHint& rHint, const TypeId& rHintType )
{
	const SbxHint* pHint = PTR_CAST( SbxHint, &rHint );

	if( pHint )
	{
		if( pHint->GetId() == SBX_HINT_INFOWANTED )
		{
			SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
			return;
		}

		SbxVariable* pVar 	= pHint->GetVar();
		SbxArray*    pPar_ 	= pVar->GetParameters();
		sal_uInt16       nWhich	= (sal_uInt16)pVar->GetUserData();
		sal_Bool		 bWrite = pHint->GetId() == SBX_HINT_DATACHANGED;

		// Propteries
		switch( nWhich )
		{
			case ATTR_IMP_BOLD:			PropBold( pVar, pPar_, bWrite ); return;
			case ATTR_IMP_ITALIC:		PropItalic( pVar, pPar_, bWrite ); return;
			case ATTR_IMP_STRIKETHROUGH:PropStrikeThrough( pVar, pPar_, bWrite ); return;
			case ATTR_IMP_UNDERLINE:	PropUnderline( pVar, pPar_, bWrite ); return;
			case ATTR_IMP_SIZE:			PropSize( pVar, pPar_, bWrite ); return;
			case ATTR_IMP_NAME:			PropName( pVar, pPar_, bWrite ); return;
		}

		SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
	}
}


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

/*
class TransferableHelperImpl : public TransferableHelper
{
    SotFormatStringId   mFormat;
    String              mString;
    Graphic             mGraphic;

    virtual void        AddSupportedFormats();
    virtual sal_Bool    GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor );

public:
    TransferableHelperImpl( void ) { mFormat = 0; }
    TransferableHelperImpl( const String& rStr )
        mFormat( FORMAT_STRING ), mString( rStr ) {}
    TransferableHelperImpl( const Graphic& rGraphic );
        mFormat( FORMAT_BITMAP ), mGraphic( rGraphic ) {}

};

void TransferableHelperImpl::AddSupportedFormats()
{
}

sal_Bool TransferableHelperImpl::GetData( const ::com::sun::star::datatransfer::DataFlavor& rFlavor )
{
	sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor );
    if( nFormat == FORMAT_STRING )
    {
    }
    else if( nFormat == FORMAT_BITMAP ||
             nFormat == FORMAT_GDIMETAFILE )
    {
    }
}
*/

void SbStdClipboard::MethClear( SbxVariable*, SbxArray* pPar_, sal_Bool )
{
	if( pPar_ && (pPar_->Count() > 1) )
	{
		StarBASIC::Error( SbERR_BAD_NUMBER_OF_ARGS );
		return;
	}

	//Clipboard::Clear();
}

void SbStdClipboard::MethGetData( SbxVariable* pVar, SbxArray* pPar_, sal_Bool )
{
    (void)pVar;

	if( !pPar_ || (pPar_->Count() != 2) )
	{
		StarBASIC::Error( SbERR_BAD_NUMBER_OF_ARGS );
		return;
	}

	sal_uInt16 nFormat = pPar_->Get(1)->GetInteger();
	if( !nFormat  || nFormat > 3 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

    /*
	if( nFormat == FORMAT_STRING )
		pVar->PutString( Clipboard::PasteString() );
	else
	if( (nFormat == FORMAT_BITMAP) ||
		(nFormat == FORMAT_GDIMETAFILE ) )
	{
		SbxObjectRef xPic = new SbStdPicture;
		Graphic aGraph;
		aGraph.Paste();
		((SbStdPicture*)(SbxObject*)xPic)->SetGraphic( aGraph );
		pVar->PutObject( xPic );
	}
    */
}

void SbStdClipboard::MethGetFormat( SbxVariable* pVar, SbxArray* pPar_, sal_Bool )
{
	if( !pPar_ || (pPar_->Count() != 2) )
	{
		StarBASIC::Error( SbERR_BAD_NUMBER_OF_ARGS );
		return;
	}

	sal_uInt16 nFormat = pPar_->Get(1)->GetInteger();
	if( !nFormat  || nFormat > 3 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

	pVar->PutBool( sal_False );
	//pVar->PutBool( Clipboard::HasFormat( nFormat ) );
}

void SbStdClipboard::MethGetText( SbxVariable* pVar, SbxArray* pPar_, sal_Bool )
{
	if( pPar_ && (pPar_->Count() > 1) )
	{
		StarBASIC::Error( SbERR_BAD_NUMBER_OF_ARGS );
		return;
	}

	pVar->PutString( String() );
	//pVar->PutString( Clipboard::PasteString() );
}

void SbStdClipboard::MethSetData( SbxVariable* pVar, SbxArray* pPar_, sal_Bool )
{
    (void)pVar;

	if( !pPar_ || (pPar_->Count() != 3) )
	{
		StarBASIC::Error( SbERR_BAD_NUMBER_OF_ARGS );
		return;
	}

	sal_uInt16 nFormat = pPar_->Get(2)->GetInteger();
	if( !nFormat  || nFormat > 3 )
	{
		StarBASIC::Error( SbERR_BAD_ARGUMENT );
		return;
	}

    /*
	if( nFormat == FORMAT_STRING )
	{
		Clipboard::CopyString( pPar_->Get(1)->GetString() );
	}
	else
	if( (nFormat == FORMAT_BITMAP) ||
		(nFormat == FORMAT_GDIMETAFILE) )
	{
		SbxObject* pObj = (SbxObject*)pPar_->Get(1)->GetObject();

		if( pObj && pObj->IsA( TYPE( SbStdPicture ) ) )
			((SbStdPicture*)(SbxObject*)pObj)->GetGraphic().Copy();
	}
    */
}

void SbStdClipboard::MethSetText( SbxVariable* pVar, SbxArray* pPar_, sal_Bool )
{
    (void)pVar;

	if( !pPar_ || (pPar_->Count() != 2) )
	{
		StarBASIC::Error( SbERR_BAD_NUMBER_OF_ARGS );
		return;
	}

	// Clipboard::CopyString( pPar_->Get(1)->GetString() );
}


TYPEINIT1( SbStdClipboard, SbxObject );

SbStdClipboard::SbStdClipboard() :
	SbxObject( String( RTL_CONSTASCII_USTRINGPARAM("Clipboard") ) )
{
	// Name Property selbst verarbeiten
	SbxVariable* p = Find( String( RTL_CONSTASCII_USTRINGPARAM("Name") ), SbxCLASS_PROPERTY );
	DBG_ASSERT( p, "Keine Name Property" );
	p->SetUserData( ATTR_IMP_NAME );

	//Methoden registrieren
	p = Make( String( RTL_CONSTASCII_USTRINGPARAM("Clear") ), SbxCLASS_METHOD, SbxEMPTY );
	p->SetFlag( SBX_DONTSTORE );
	p->SetUserData( METH_CLEAR );
	p = Make( String( RTL_CONSTASCII_USTRINGPARAM("GetData") ), SbxCLASS_METHOD, SbxEMPTY );
	p->SetFlag( SBX_DONTSTORE );
	p->SetUserData( METH_GETDATA );
	p = Make( String( RTL_CONSTASCII_USTRINGPARAM("GetFormat") ), SbxCLASS_METHOD, SbxEMPTY );
	p->SetFlag( SBX_DONTSTORE );
	p->SetUserData( METH_GETFORMAT );
	p = Make( String( RTL_CONSTASCII_USTRINGPARAM("GetText") ), SbxCLASS_METHOD, SbxEMPTY );
	p->SetFlag( SBX_DONTSTORE );
	p->SetUserData( METH_GETTEXT );
	p = Make( String( RTL_CONSTASCII_USTRINGPARAM("SetData") ), SbxCLASS_METHOD, SbxEMPTY );
	p->SetFlag( SBX_DONTSTORE );
	p->SetUserData( METH_SETDATA );
	p = Make( String( RTL_CONSTASCII_USTRINGPARAM("SetText") ), SbxCLASS_METHOD, SbxEMPTY );
	p->SetFlag( SBX_DONTSTORE );
	p->SetUserData( METH_SETTEXT );
}

SbStdClipboard::~SbStdClipboard()
{
}


SbxVariable* SbStdClipboard::Find( const String& rName, SbxClassType t )
{
	// Bereits eingetragen?
	return SbxObject::Find( rName, t );
}



void SbStdClipboard::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
								 const SfxHint& rHint, const TypeId& rHintType )
{
	const SbxHint* pHint = PTR_CAST( SbxHint, &rHint );

	if( pHint )
	{
		if( pHint->GetId() == SBX_HINT_INFOWANTED )
		{
			SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
			return;
		}

		SbxVariable* pVar 	= pHint->GetVar();
		SbxArray*    pPar_ 	= pVar->GetParameters();
		sal_uInt16       nWhich	= (sal_uInt16)pVar->GetUserData();
		sal_Bool		 bWrite = pHint->GetId() == SBX_HINT_DATACHANGED;

		// Methods
		switch( nWhich )
		{
			case METH_CLEAR:			MethClear( pVar, pPar_, bWrite ); return;
			case METH_GETDATA:			MethGetData( pVar, pPar_, bWrite ); return;
			case METH_GETFORMAT:		MethGetFormat( pVar, pPar_, bWrite ); return;
			case METH_GETTEXT:			MethGetText( pVar, pPar_, bWrite ); return;
			case METH_SETDATA:			MethSetData( pVar, pPar_, bWrite ); return;
			case METH_SETTEXT:			MethSetText( pVar, pPar_, bWrite ); return;
		}

		SbxObject::SFX_NOTIFY( rBC, rBCType, rHint, rHintType );
	}
}
