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

#include <com/sun/star/awt/PosSize.hpp>
#include <com/sun/star/awt/XActionListener.hpp>
#include <com/sun/star/awt/XButton.hpp>
#include <com/sun/star/awt/XCheckBox.hpp>
#include <com/sun/star/awt/XRadioButton.hpp>
#include <com/sun/star/graphic/XGraphic.hpp>
#include <cppuhelper/implbase1.hxx>
#include <toolkit/awt/vclxwindow.hxx>
#include <toolkit/awt/vclxwindows.hxx>
#include <toolkit/helper/convert.hxx>
#include <vcl/button.hxx>
#include <vcl/event.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/svapp.hxx>
#include <vcl/window.hxx>

#include <list>

#include <layout/core/helper.hxx>

using namespace ::com::sun::star;

using rtl::OUString;

namespace layout
{

class ImageImpl
{
  public:
    uno::Reference< graphic::XGraphic > mxGraphic;
    ImageImpl( const char *pName )
        : mxGraphic( layoutimpl::loadGraphic( pName ) )
    {
        if ( !mxGraphic.is() )
        {
            DBG_ERROR1( "ERROR: failed to load image: `%s'\n", pName );
        }
    }
};

Image::Image( const char *pName )
    : pImpl( new ImageImpl( pName ) )
{
}

Image::~Image()
{
    delete pImpl;
}

class ButtonImpl : public ControlImpl
                 , public ::cppu::WeakImplHelper1< awt::XActionListener >
{
    Link maClickHdl;

public:
    uno::Reference< awt::XButton > mxButton;
    ButtonImpl( Context *context, const PeerHandle &peer, Window *window )
        : ControlImpl( context, peer, window )
        , mxButton( peer, uno::UNO_QUERY )
    {
        /* We have default action when clicked, always listen. */
        mxButton->addActionListener( this );
    }

    ~ButtonImpl()
    {
    }

    virtual void Click() { /* make me pure virtual? */ };

    Link& GetClickHdl ()
    {
        return maClickHdl;
    }

    virtual void SetClickHdl( Link const& link )
    {
        maClickHdl = link;
    }

    void SAL_CALL disposing( lang::EventObject const& e )
        throw (uno::RuntimeException)
    {
        mxButton->removeActionListener( this );
        ControlImpl::disposing (e);
        mxButton.clear ();
    }

    virtual void SAL_CALL actionPerformed( const awt::ActionEvent& )
        throw (uno::RuntimeException)
    {
        if ( !maClickHdl )
            Click();
        else
            maClickHdl.Call( static_cast<Window *>( mpWindow ) );
    }

    bool SetModeImage( uno::Reference< graphic::XGraphic > xGraph )
    {
        setProperty( "Graphic", uno::Any( xGraph ) );
        return true;
    }
};

Button::~Button ()
{
}

String Button::GetStandardText (sal_uInt16 button_type)
{
    return ::Button::GetStandardText (button_type);
}

void Button::SetText( OUString const& rStr )
{
    if ( !getImpl()->mxButton.is() )
        return;
    getImpl()->mxButton->setLabel( rStr );
}

void Button::SetClickHdl( const Link& link )
{
    if (getImpl() && getImpl()->mxButton.is ())
        getImpl()->SetClickHdl( link );
}

Link& Button::GetClickHdl ()
{
    return getImpl()->GetClickHdl ();
}

bool Button::SetModeImage (Image const& image)
{
    return getImpl() || getImpl()->SetModeImage (image.getImpl().mxGraphic);
}

bool Button::SetModeImage (::Image const& image, BmpColorMode mode)
{
    return !GetButton () || GetButton ()->SetModeImage (image, mode);
}

void Button::SetImageAlign( ImageAlign eAlign )
{
    if ( getImpl() )
        getImpl()->setProperty( "ImageAlign", uno::Any( (sal_Int16) eAlign ) );
}

void Button::Click()
{
}

IMPL_GET_IMPL( Button );
IMPL_CONSTRUCTORS( Button, Control, "button" );
IMPL_GET_WINDOW (Button);

class PushButtonImpl : public ButtonImpl
                 , public ::cppu::WeakImplHelper1< awt::XItemListener >
{
    Link maToggleHdl;
public:
    PushButtonImpl( Context *context, const PeerHandle &peer, Window *window )
        : ButtonImpl( context, peer, window )
    {
    }

    void SetToggleHdl( const Link& link )
    {
        // XButton doesn't have an explicit event for Toggle. Anyway, it is a
        // superset of the clicks: all clicks, and explicit toggles
        if (!link && !!maToggleHdl)
            mxButton->removeActionListener( this );
        else if (!!link && !maToggleHdl)
            mxButton->addActionListener( this );
        maToggleHdl = link;
    }
    void SAL_CALL disposing( lang::EventObject const& e )
        throw (uno::RuntimeException)
    {
        ButtonImpl::disposing (e);
    }
    virtual void SAL_CALL actionPerformed( awt::ActionEvent const& e )
        throw (uno::RuntimeException)
    {
        ButtonImpl::actionPerformed( e );
        fireToggle();
    }
    virtual void SAL_CALL itemStateChanged( const awt::ItemEvent& )
        throw (uno::RuntimeException)
    {
        maToggleHdl.Call( static_cast<Window *>( mpWindow ) );
    }
    void fireToggle()
    {
        maToggleHdl.Call(  static_cast<Window *>( mpWindow ) );
    }

};

PushButton::~PushButton ()
{
    SetToggleHdl (Link ());
}

void PushButton::Check( bool bCheck )
{
    if ( getImpl() )
        getImpl()->setProperty( "State", uno::Any( (sal_Int16) !!bCheck ) );
    // XButton doesn't have explicit toggle event
    getImpl()->fireToggle();
}

bool PushButton::IsChecked() const
{
    return !!( getImpl() && getImpl()->getProperty( "State" ).get< sal_Int16 >() );
}

void PushButton::Toggle()
{
    Check( true );
}

void PushButton::SetToggleHdl( const Link& link )
{
    if (getImpl() && getImpl()->mxButton.is ())
        getImpl()->SetToggleHdl( link );
}

IMPL_GET_IMPL( PushButton );
IMPL_CONSTRUCTORS( PushButton, Button, "pushbutton" );
IMPL_GET_WINDOW (PushButton);

class RadioButtonImpl : public ButtonImpl
                      , public ::cppu::WeakImplHelper1< awt::XItemListener >
{
    Link maToggleHdl;
public:
    uno::Reference< awt::XRadioButton > mxRadioButton;
    RadioButtonImpl( Context *context, const PeerHandle &peer, Window *window )
        : ButtonImpl( context, peer, window )
        , mxRadioButton( peer, uno::UNO_QUERY )
    {
    }

    void Check( bool bCheck )
    {
        if ( !mxRadioButton.is() )
            return;

#if 1
        // Have setState fire item event for
        // RadioGroups::RadioGroup::itemStateChanged ()
        ::RadioButton *r = static_cast<RadioButton*>(mpWindow)->GetRadioButton ();
        bool state = r->IsRadioCheckEnabled ();
        r->EnableRadioCheck();
        mxRadioButton->setState( !!bCheck );
        r->EnableRadioCheck (state);
#else
        mxRadioButton->setState( !!bCheck );
#endif
        fireToggle();
    }

    bool IsChecked()
    {
        if ( !mxRadioButton.is() )
            return false;
        return mxRadioButton->getState();
    }

    void SetToggleHdl( const Link& link )
    {
        if (!link && !!maToggleHdl)
            mxRadioButton->removeItemListener( this );
        else if (!!link && !maToggleHdl)
            mxRadioButton->addItemListener( this );
        maToggleHdl = link;
    }

    inline void fireToggle()
    {
        maToggleHdl.Call(  static_cast<Window *>( mpWindow ) );
    }

    virtual void SetClickHdl( const Link& link )
    {
        // Keep RadioGroups::RadioGroup's actionListener at HEAD
        // of list.  This way, it can handle RadioGroup's button
        // states before all other callbacks and make sure the
        // client code has the right state.

        // IWBN to add an XRadioButton2 and layout::VCLXRadioButton
        // with {get,set}RadioGroup() (and a "radiogroup" property
        // even) and handle the grouping here in RadioButtonImpl.
        uno::Reference< uno::XInterface > x = static_cast<VCLXRadioButton*> (mpWindow->GetVCLXWindow ())->getFirstActionListener ();
        uno::Reference< awt::XActionListener > a = uno::Reference< awt::XActionListener> (x ,uno::UNO_QUERY );
        mxButton->removeActionListener (a);
        ButtonImpl::SetClickHdl (link);
        mxButton->addActionListener (a);
    }

    void SAL_CALL disposing( lang::EventObject const& e )
        throw (uno::RuntimeException)
    {
        ButtonImpl::disposing (e);
    }

    virtual void SAL_CALL itemStateChanged( const awt::ItemEvent& )
        throw (uno::RuntimeException)
    {
        maToggleHdl.Call( static_cast<Window *>( mpWindow ) );
    }
};

RadioButton::~RadioButton ()
{
    SetToggleHdl (Link ());
}

void RadioButton::Check( bool bCheck )
{
    getImpl()->Check( bCheck );
}

bool RadioButton::IsChecked() const
{
    return getImpl()->IsChecked();
}

void RadioButton::SetToggleHdl( const Link& link )
{
    if (getImpl() && getImpl()->mxRadioButton.is ())
        getImpl()->SetToggleHdl( link );
}

IMPL_GET_IMPL( RadioButton );
IMPL_GET_WINDOW( RadioButton );
IMPL_GET_VCLXWINDOW( RadioButton );
IMPL_CONSTRUCTORS( RadioButton, Button, "radiobutton" );

class CheckBoxImpl : public ButtonImpl
                 , public ::cppu::WeakImplHelper1< awt::XItemListener >
{
    Link maToggleHdl;
  public:
    uno::Reference< awt::XCheckBox > mxCheckBox;
    CheckBoxImpl( Context *context, const PeerHandle &peer, Window *window )
        : ButtonImpl( context, peer, window )
        , mxCheckBox( peer, uno::UNO_QUERY )
    {
    }

    void SetToggleHdl( const Link& link )
    {
        if (!link && !!maToggleHdl)
            mxCheckBox->removeItemListener( this );
        else if (!!link && !maToggleHdl)
            mxCheckBox->addItemListener( this );
        maToggleHdl = link;
    }
    void SAL_CALL disposing( lang::EventObject const& e )
        throw (uno::RuntimeException)
    {
        ButtonImpl::disposing (e);
    }
    virtual void SAL_CALL itemStateChanged( const awt::ItemEvent& )
        throw (uno::RuntimeException)
    {
        maToggleHdl.Call( static_cast<Window *>( mpWindow ) );
    }
};

CheckBox::~CheckBox ()
{
    SetToggleHdl (Link ());
}

void CheckBox::Check( bool bCheck )
{
    if ( !getImpl()->mxCheckBox.is() )
        return;
    getImpl()->mxCheckBox->setState( !!bCheck );
}

bool CheckBox::IsChecked() const
{
    if ( !getImpl()->mxCheckBox.is() )
        return false;
    return getImpl()->mxCheckBox->getState() != 0;
}

void CheckBox::SetToggleHdl( const Link& link )
{
    if (getImpl() && getImpl()->mxCheckBox.is ())
        getImpl()->SetToggleHdl( link );
}

IMPL_GET_IMPL( CheckBox );
IMPL_CONSTRUCTORS( CheckBox, Button, "checkbox" );

#define BUTTON_IMPL(t, parent, response) \
    class t##Impl : public parent##Impl \
    { \
    public: \
        t##Impl( Context *context, PeerHandle const& peer, Window *window ) \
            : parent##Impl( context, peer, window ) \
        { \
        } \
        void Click() \
        { \
            if (Dialog *d = static_cast<Dialog *> (mpCtx)) \
                d->EndDialog( response ); \
        } \
    }

/* Common button types currently unavailable in OOo: */
/* mpReset */
/* mpApply */
/* mpAction */
#define RET_RESET 6
#define RET_APPLY 7
#define BUTTONID_RESET RET_RESET
#define BUTTONID_APPLY RET_APPLY

BUTTON_IMPL( OKButton, PushButton, BUTTONID_OK );
BUTTON_IMPL( CancelButton, PushButton, BUTTONID_CANCEL );
BUTTON_IMPL( YesButton, PushButton, BUTTONID_YES );
BUTTON_IMPL( NoButton, PushButton, BUTTONID_NO );
BUTTON_IMPL( RetryButton, PushButton, BUTTONID_RETRY );
BUTTON_IMPL( IgnoreButton, PushButton, BUTTONID_IGNORE );
BUTTON_IMPL( ResetButton, PushButton, BUTTONID_RESET );
BUTTON_IMPL( ApplyButton, PushButton, BUTTONID_APPLY ); /* Deprecated? */
BUTTON_IMPL( HelpButton, PushButton, BUTTONID_HELP );

IMPL_CONSTRUCTORS( OKButton, PushButton, "okbutton" );
IMPL_CONSTRUCTORS( CancelButton, PushButton, "cancelbutton" );
IMPL_CONSTRUCTORS( YesButton, PushButton, "yesbutton" );
IMPL_CONSTRUCTORS( NoButton, PushButton, "nobutton" );
IMPL_CONSTRUCTORS( RetryButton, PushButton, "retrybutton" );
IMPL_CONSTRUCTORS( IgnoreButton, PushButton, "ignorebutton" );
IMPL_CONSTRUCTORS( ResetButton, PushButton, "resetbutton" );
IMPL_CONSTRUCTORS( ApplyButton, PushButton, "applybutton" );  /* Deprecated? */
IMPL_CONSTRUCTORS( HelpButton, PushButton, "helpbutton" );

IMPL_IMPL (ImageButton, PushButton)


IMPL_CONSTRUCTORS( ImageButton, PushButton, "imagebutton" );

class AdvancedButtonImpl : public PushButtonImpl
{
protected:
    bool bAdvancedMode;
    std::list< Window*> maAdvanced;
    std::list< Window*> maSimple;

public:
    rtl::OUString mAdvancedLabel;
    rtl::OUString mSimpleLabel;

protected:
    Window* Remove( std::list< Window*> lst, Window* w )
    {
        for ( std::list< Window*>::iterator it = maAdvanced.begin();
              it != maAdvanced.end(); it++ )
            if ( *it == w )
            {
                lst.erase( it );
                return *it;
            }
        return 0;
    }

public:
    AdvancedButtonImpl( Context *context, PeerHandle const& peer, Window *window )
        : PushButtonImpl( context, peer, window )
        , bAdvancedMode( false )
          // TODO: i18n
          // Button::GetStandardText( BUTTON_ADVANCED );
          // Button::GetStandardText( BUTTON_SIMPLE );
        , mAdvancedLabel( rtl::OUString::createFromAscii( "Advanced..." ) )
        , mSimpleLabel( rtl::OUString::createFromAscii( "Simple..." ) )
    {
    }
    void Click()
    {
        bAdvancedMode = !bAdvancedMode;
        if ( bAdvancedMode )
            advancedMode();
        else
            simpleMode();
    }
    void setAlign ()
    {
        ::PushButton *b = static_cast<PushButton*> (mpWindow)->GetPushButton ();
        b->SetSymbolAlign (SYMBOLALIGN_RIGHT);
        b->SetSmallSymbol ();
        //mpWindow->SetStyle (mpWindow->GetStyle() | WB_CENTER);
    }
    void advancedMode()
    {
        ::PushButton *b = static_cast<PushButton*> (mpWindow)->GetPushButton ();
        b->SetSymbol (SYMBOL_PAGEUP);
        setAlign ();
        if (mSimpleLabel.getLength ())
            b->SetText (mSimpleLabel);
        for ( std::list< Window*>::iterator it = maAdvanced.begin();
              it != maAdvanced.end(); it++ )
            ( *it )->Show();
        for ( std::list< Window*>::iterator it = maSimple.begin();
              it != maSimple.end(); it++ )
            ( *it )->Hide();

        redraw ();
    }
    void simpleMode()
    {
        //mxButton->setLabel( mSimpleLabel );
        ::PushButton *b = static_cast<PushButton*> (mpWindow)->GetPushButton ();
        b->SetSymbol (SYMBOL_PAGEDOWN);
        if (mAdvancedLabel.getLength ())
            b->SetText (mAdvancedLabel);
        setAlign ();
        for ( std::list< Window*>::iterator it = maAdvanced.begin();
              it != maAdvanced.end(); it++ )
            ( *it )->Hide();
        for ( std::list< Window*>::iterator it = maSimple.begin();
              it != maSimple.end(); it++ )
            ( *it )->Show();

        redraw (true);
    }
    void AddAdvanced( Window* w )
    {
        maAdvanced.push_back( w );
        if ( !bAdvancedMode )
            w->Hide();
    }
    void AddSimple( Window* w )
    {
        maSimple.push_back( w );
        if ( bAdvancedMode )
            w->Hide();
    }
    void RemoveAdvanced( Window* w )
    {
        Remove( maAdvanced, w );
    }
    void RemoveSimple( Window* w )
    {
        Remove( maSimple, w );
    }
};

void AdvancedButton::AddAdvanced( Window* w )
{
    getImpl()->AddAdvanced( w );
}

void AdvancedButton::AddSimple( Window* w )
{
    getImpl()->AddSimple( w );
}

void AdvancedButton::RemoveAdvanced( Window* w )
{
    getImpl()->RemoveAdvanced( w );
}

void AdvancedButton::RemoveSimple( Window* w )
{
    getImpl()->RemoveSimple( w );
}

void AdvancedButton::SetAdvancedText (rtl::OUString const& text)
{
    if (text.getLength ())
        getImpl()->mAdvancedLabel = text;
}

void AdvancedButton::SetSimpleText (rtl::OUString const& text)
{
    if (text.getLength ())
        getImpl()->mSimpleLabel = text;
}

rtl::OUString AdvancedButton::GetAdvancedText () const
{
    return getImpl()->mAdvancedLabel;
}

rtl::OUString AdvancedButton::GetSimpleText () const
{
    return getImpl()->mSimpleLabel;
}

void AdvancedButton::SetDelta (int)
{
}

IMPL_CONSTRUCTORS_BODY( AdvancedButton, PushButton, "advancedbutton", getImpl()->simpleMode () );
IMPL_GET_IMPL( AdvancedButton );


class MoreButtonImpl : public AdvancedButtonImpl
{
public:
    MoreButtonImpl( Context *context, PeerHandle const& peer, Window *window )
        : AdvancedButtonImpl( context, peer, window)
    {
        mSimpleLabel = Button::GetStandardText( BUTTON_MORE );
        mAdvancedLabel = Button::GetStandardText( BUTTON_LESS );
    }
    void AddWindow( Window* w ) { AddAdvanced( w ); }
    void RemoveWindow( Window* w ) { RemoveAdvanced( w ); }
};

// TODO
//BUTTON_IMPL( MoreButton, PushButton, 0 );
IMPL_CONSTRUCTORS_BODY( MoreButton, AdvancedButton, "morebutton", getImpl()->simpleMode () );
IMPL_GET_IMPL( MoreButton );

void MoreButton::AddWindow( Window* w )
{
    getImpl()->AddWindow( w );
}

void MoreButton::RemoveWindow( Window* w )
{
    getImpl()->RemoveWindow( w );
}

void MoreButton::SetMoreText (rtl::OUString const& text)
{
    SetAdvancedText (text);
}

void MoreButton::SetLessText (rtl::OUString const& text)
{
    SetSimpleText (text);
}

rtl::OUString MoreButton::GetMoreText () const
{
    return GetAdvancedText ();
}

rtl::OUString MoreButton::GetLessText () const
{
    return GetSimpleText ();
}

} // namespace layout
