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



#include "vclxdialog.hxx"

#include <com/sun/star/awt/PosSize.hpp>
#include <com/sun/star/awt/SystemDependentXWindow.hpp>
#include <com/sun/star/lang/SystemDependent.hpp>

#include <cppuhelper/typeprovider.hxx>

#include <toolkit/awt/vclxmenu.hxx>
#include <toolkit/helper/macros.hxx>
#include <toolkit/helper/property.hxx>

#ifdef WNT
#include <tools/prewin.h>
#include <windows.h>
#include <tools/postwin.h>
#elif defined ( OS2 )
#include <svpm.h>
#elif defined ( QUARTZ )
#include "premac.h"
#include <Cocoa/Cocoa.h>
#include "postmac.h"
#endif

#include <vcl/dialog.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/svapp.hxx>
#include <vcl/sysdata.hxx>
#include <vcl/wrkwin.hxx>

#include "forward.hxx"

namespace layoutimpl
{

DBG_NAME( VCLXDialog )

VCLXDialog::VCLXDialog()
    : VCLXWindow()
    , VCLXTopWindow_Base( true )
    , VCLXDialog_Base()
    , Bin()
    , bRealized( false )
    , bResizeSafeguard( false )
{
    DBG_CTOR( VCLXDialog, NULL );

/*        mxLayoutUnit = uno::Reference< awt::XLayoutUnit >( new LayoutUnit() );
          assert(mxLayoutUnit.is());*/
}

VCLXDialog::~VCLXDialog()
{
    DBG_DTOR( VCLXDialog, NULL );
}

vos::IMutex& VCLXDialog::GetMutexImpl()
{
    return VCLXWindow::GetMutex();
}

Window* VCLXDialog::GetWindowImpl()
{
    return VCLXWindow::GetWindow();
}

::cppu::OInterfaceContainerHelper& VCLXDialog::GetTopWindowListenersImpl()
{
    return GetTopWindowListeners();
}

IMPLEMENT_2_FORWARD_XINTERFACE2( VCLXDialog, VCLXWindow, Bin, VCLXDialog_Base );

IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXDialog, VCLXWindow, VCLXDialog_Base );

void SAL_CALL VCLXDialog::dispose() throw(::com::sun::star::uno::RuntimeException)
{
    {
        ::vos::OGuard aGuard( GetMutex() );

        ::com::sun::star::lang::EventObject aDisposeEvent;
        aDisposeEvent.Source = W3K_EXPLICIT_CAST (*this);
//            maTabListeners.disposeAndClear( aDisposeEvent );
    }

    VCLXWindow::dispose();
}

void VCLXDialog::resizedCb()
{
    queueResize();
}

void SAL_CALL VCLXDialog::allocateArea( const css::awt::Rectangle &rArea )
    throw (css::uno::RuntimeException)
{
    ::com::sun::star::awt::Size reqSize = Bin::getMinimumSize();
    reqSize.Height = getHeightForWidth( rArea.Width );

    if ( !bRealized )
    {
        setPosSize( 0, 0, reqSize.Width, reqSize.Height, ::com::sun::star::awt::PosSize::SIZE );
        bRealized = true;
        setVisible( true );
    }
    else
    {
        ::com::sun::star::awt::Size curSize = getSize();
        if ( reqSize.Width > curSize.Width )
            setPosSize( 0, 0, reqSize.Width, 0, ::com::sun::star::awt::PosSize::WIDTH );
        if ( reqSize.Height > curSize.Height )
            setPosSize( 0, 0, 0, reqSize.Height, ::com::sun::star::awt::PosSize::HEIGHT );
    }

    ::com::sun::star::awt::Size size = getSize();
    maAllocation.Width = size.Width;
    maAllocation.Height = size.Height;

    Bin::allocateArea( maAllocation );
}

void VCLXDialog::ProcessWindowEvent( const VclWindowEvent& _rVclWindowEvent )
{
    ::vos::OClearableGuard aGuard( GetMutex() );

    switch ( _rVclWindowEvent.GetId() )
    {
        case VCLEVENT_WINDOW_RESIZE:
            resizedCb();
        default:
            aGuard.clear();
            VCLXWindow::ProcessWindowEvent( _rVclWindowEvent );
            break;
    }
}

void SAL_CALL VCLXDialog::setProperty( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Any &Value ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    if ( GetWindow() )
    {
/*        sal_uInt16 nPropertyId = GetPropertyId( PropertyName );
        switch ( nPropertyId )
        {
            default:
*/
                VCLXWindow::setProperty( PropertyName, Value );
/*        }
*/
    }
}

::com::sun::star::uno::Any SAL_CALL VCLXDialog::getProperty( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    ::com::sun::star::uno::Any aReturn;
    if ( GetWindow() )
    {
/*
        sal_uInt16 nPropertyId = GetPropertyId( PropertyName );
        switch ( nPropertyId )
        {
            default:
*/
                aReturn = VCLXWindow::getProperty( PropertyName );
/*
        }
*/
    }
    return aReturn;
}

void VCLXDialog::setTitle( const ::rtl::OUString& Title ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    Window* pWindow = GetWindow();
    if ( pWindow )
        pWindow->SetText( Title );
}

void VCLXDialog::setHelpId( const rtl::OUString& rId ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    Window* pWindow = GetWindow();
    if ( pWindow )
        pWindow->SetHelpId( rtl::OUStringToOString( rId, RTL_TEXTENCODING_UTF8 ) );
}

::rtl::OUString VCLXDialog::getTitle() throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    ::rtl::OUString aTitle;
    Window* pWindow = GetWindow();
    if ( pWindow )
        aTitle = pWindow->GetText();
    return aTitle;
}

sal_Int16 VCLXDialog::execute() throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    sal_Int16 nRet = 0;
    if ( GetWindow() )
    {
        Dialog* pDlg = (Dialog*) GetWindow();
        Window* pParent = pDlg->GetWindow( WINDOW_PARENTOVERLAP );
        Window* pOldParent = NULL;
        if ( pParent && !pParent->IsReallyVisible() )
        {
            pOldParent = pDlg->GetParent();
            Window* pFrame = pDlg->GetWindow( WINDOW_FRAME );
            if ( pFrame != pDlg )
                pDlg->SetParent( pFrame );
        }
        nRet = pDlg->Execute();
        if ( pOldParent )
            pDlg->SetParent( pOldParent );
    }
    return nRet;
}

void VCLXDialog::endDialog( sal_Int32 nResult ) throw(::com::sun::star::uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    if ( nResult == BUTTONID_HELP )
    {
        // UGH: c&p button.cxx
        ::Window* pFocusWin = Application::GetFocusWindow();
        if ( !pFocusWin )
            pFocusWin = GetWindow();

        HelpEvent aEvt( pFocusWin->GetPointerPosPixel(), HELPMODE_CONTEXT );
        pFocusWin->RequestHelp( aEvt );
        return;
    }

    Dialog* pDlg = (Dialog*) GetWindow();
    if ( pDlg )
        pDlg->EndDialog( nResult );
}

void VCLXDialog::endExecute() throw(::com::sun::star::uno::RuntimeException)
{
    endDialog( 0 );
}

} // namespace layoutimpl
