/**************************************************************
 * 
 * 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_svtools.hxx"
#include <svtools/editbrowsebox.hxx>
#include <vcl/decoview.hxx>
#include <svtools/fmtfield.hxx>
#include <svtools/xtextedt.hxx>

#include <algorithm>

// .......................................................................
namespace svt
{
// .......................................................................

	//==================================================================
	//= ComboBoxControl
	//==================================================================
	ComboBoxControl::ComboBoxControl(Window* pParent, WinBits nWinStyle)
				   :ComboBox(pParent, nWinStyle|WB_DROPDOWN|WB_NOBORDER)
	{
		EnableAutoSize(sal_False);
		EnableAutocomplete(sal_True);
		SetDropDownLineCount(5);
	}

	//------------------------------------------------------------------
	long ComboBoxControl::PreNotify( NotifyEvent& rNEvt )
	{
		switch (rNEvt.GetType())
		{
			case EVENT_KEYINPUT:
				if (!IsInDropDown())
				{
					const KeyEvent *pEvt = rNEvt.GetKeyEvent();
					const KeyCode rKey = pEvt->GetKeyCode();

					if ((rKey.GetCode() == KEY_UP || rKey.GetCode() == KEY_DOWN) &&
						(!pEvt->GetKeyCode().IsShift() && pEvt->GetKeyCode().IsMod1()))
					{
						// select next resp. previous entry
						int nPos = GetEntryPos(GetText());
						nPos = nPos + (rKey.GetCode() == KEY_DOWN ? 1 : -1);
						if (nPos < 0)
							nPos = 0;
						if (nPos >= GetEntryCount())
							nPos = GetEntryCount() - 1;
						SetText(GetEntry(sal::static_int_cast< sal_uInt16 >(nPos)));
						return 1;
					}
				}
				break;
		}
		return ComboBox::PreNotify(rNEvt);
	}

	//==================================================================
	//= ComboBoxCellController
	//==================================================================
	//------------------------------------------------------------------
	ComboBoxCellController::ComboBoxCellController(ComboBoxControl* pWin)
							 :CellController(pWin)
	{
	}

	//------------------------------------------------------------------
	sal_Bool ComboBoxCellController::MoveAllowed(const KeyEvent& rEvt) const
	{
		ComboBoxControl& rBox = GetComboBox();
		switch (rEvt.GetKeyCode().GetCode())
		{
			case KEY_END:
			case KEY_RIGHT:
			{
				Selection aSel = rBox.GetSelection();
				return !aSel && aSel.Max() == rBox.GetText().Len();
			}
			case KEY_HOME:
			case KEY_LEFT:
			{
				Selection aSel = rBox.GetSelection();
				return !aSel && aSel.Min() == 0;
			}
			case KEY_UP:
			case KEY_DOWN:
				if (rBox.IsInDropDown())
					return sal_False;
				if (!rEvt.GetKeyCode().IsShift() &&
					 rEvt.GetKeyCode().IsMod1())
					return sal_False;
				// drop down the list box
				else if (rEvt.GetKeyCode().IsMod2() && rEvt.GetKeyCode().GetCode() == KEY_DOWN)
					return sal_False;
			case KEY_PAGEUP:
			case KEY_PAGEDOWN:
			case KEY_RETURN:
				if (rBox.IsInDropDown())
					return sal_False;
			default:
				return sal_True;
		}
	}

	//------------------------------------------------------------------
	sal_Bool ComboBoxCellController::IsModified() const
	{
		return GetComboBox().GetSavedValue() != GetComboBox().GetText();
	}

	//------------------------------------------------------------------
	void ComboBoxCellController::ClearModified()
	{
		GetComboBox().SaveValue();
	}

	//------------------------------------------------------------------
	void ComboBoxCellController::SetModifyHdl(const Link& rLink)
	{
		GetComboBox().SetModifyHdl(rLink);
	}

	//==================================================================
	//= ListBoxControl
	//==================================================================
	//------------------------------------------------------------------
	ListBoxControl::ListBoxControl(Window* pParent, WinBits nWinStyle)
				  :ListBox(pParent, nWinStyle|WB_DROPDOWN|WB_NOBORDER)
	{
		EnableAutoSize(sal_False);
		EnableMultiSelection(sal_False);
		SetDropDownLineCount(20);
	}

	//------------------------------------------------------------------
	long ListBoxControl::PreNotify( NotifyEvent& rNEvt )
	{
		switch (rNEvt.GetType())
		{
			case EVENT_KEYINPUT:
				if (!IsInDropDown())
				{
					const KeyEvent *pEvt = rNEvt.GetKeyEvent();
					const KeyCode rKey = pEvt->GetKeyCode();

					if ((rKey.GetCode() == KEY_UP || rKey.GetCode() == KEY_DOWN) &&
						(!pEvt->GetKeyCode().IsShift() && pEvt->GetKeyCode().IsMod1()))
					{
						// select next resp. previous entry
						int nPos = GetSelectEntryPos();
						nPos = nPos + (rKey.GetCode() == KEY_DOWN ? 1 : -1);
						if (nPos < 0)
							nPos = 0;
						if (nPos >= GetEntryCount())
							nPos = GetEntryCount() - 1;
						SelectEntryPos(sal::static_int_cast< sal_uInt16 >(nPos));
						Select();	// for calling Modify
						return 1;
					}
					else if (GetParent()->PreNotify(rNEvt))
						return 1;
				}
				break;
		}
		return ListBox::PreNotify(rNEvt);
	}

	//==================================================================
	//= ListBoxCellController
	//==================================================================
	//------------------------------------------------------------------
	ListBoxCellController::ListBoxCellController(ListBoxControl* pWin)
							 :CellController(pWin)
	{
	}

	//------------------------------------------------------------------
	sal_Bool ListBoxCellController::MoveAllowed(const KeyEvent& rEvt) const
	{
		ListBoxControl& rBox = GetListBox();
		switch (rEvt.GetKeyCode().GetCode())
		{
			case KEY_UP:
			case KEY_DOWN:
				if (!rEvt.GetKeyCode().IsShift() &&
					 rEvt.GetKeyCode().IsMod1())
					return sal_False;
				// drop down the list box
				else
					if (rEvt.GetKeyCode().IsMod2() && rEvt.GetKeyCode().GetCode() == KEY_DOWN)
						return sal_False;
			case KEY_PAGEUP:
			case KEY_PAGEDOWN:
				if (rBox.IsTravelSelect())
					return sal_False;
			default:
				return sal_True;
		}
	}

	//------------------------------------------------------------------
	sal_Bool ListBoxCellController::IsModified() const
	{
		return GetListBox().GetSelectEntryPos() != GetListBox().GetSavedValue();
	}

	//------------------------------------------------------------------
	void ListBoxCellController::ClearModified()
	{
		GetListBox().SaveValue();
	}

	//------------------------------------------------------------------
	void ListBoxCellController::SetModifyHdl(const Link& rLink)
	{
		GetListBox().SetSelectHdl(rLink);
	}

	//==================================================================
	//= CheckBoxControl
	//==================================================================
	//------------------------------------------------------------------
	CheckBoxControl::CheckBoxControl(Window* pParent, WinBits nWinStyle)
				   :Control(pParent, nWinStyle)
	{
		const Wallpaper& rParentBackground = pParent->GetBackground();
		if ( (pParent->GetStyle() & WB_CLIPCHILDREN) || rParentBackground.IsFixed() )
			SetBackground( rParentBackground );
		else
		{
			SetPaintTransparent( sal_True );
			SetBackground();
		}

		EnableChildTransparentMode();

		pBox = new TriStateBox(this,WB_CENTER|WB_VCENTER);
		pBox->EnableChildTransparentMode();
		pBox->SetPaintTransparent( sal_True );
		pBox->SetClickHdl( LINK( this, CheckBoxControl, OnClick ) );
		pBox->Show();
	}

	//------------------------------------------------------------------
	CheckBoxControl::~CheckBoxControl()
	{
		delete pBox;
	}

	//------------------------------------------------------------------
	IMPL_LINK( CheckBoxControl, OnClick, void*, EMPTYARG )
	{
		m_aClickLink.Call(pBox);
		return m_aModifyLink.Call(pBox);
	}

	//------------------------------------------------------------------
	void CheckBoxControl::Resize()
	{
		Control::Resize();
		pBox->SetPosSizePixel(Point(0,0),GetSizePixel());
	}

	//------------------------------------------------------------------------------
	void CheckBoxControl::DataChanged( const DataChangedEvent& _rEvent )
    {
        if ( _rEvent.GetType() == DATACHANGED_SETTINGS )
            pBox->SetSettings( GetSettings() );
    }

	//------------------------------------------------------------------------------
	void CheckBoxControl::StateChanged( StateChangedType nStateChange )
	{
		Control::StateChanged(nStateChange);
		if ( nStateChange == STATE_CHANGE_ZOOM )
			pBox->SetZoom(GetZoom());
	}

	//------------------------------------------------------------------
	void CheckBoxControl::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags )
	{
		pBox->Draw(pDev,rPos,rSize,nFlags);
	}

	//------------------------------------------------------------------
	void CheckBoxControl::GetFocus()
	{
		pBox->GrabFocus();
	}

	//------------------------------------------------------------------
	void CheckBoxControl::Paint(const Rectangle& rClientRect)
	{
		Control::Paint(rClientRect);
		if (HasFocus())
			ShowFocus(aFocusRect);
	}

	//------------------------------------------------------------------
	long CheckBoxControl::PreNotify(NotifyEvent& rEvt)
	{
		switch (rEvt.GetType())
		{
			case EVENT_GETFOCUS:
				ShowFocus(aFocusRect);
				break;
			case EVENT_LOSEFOCUS:
				HideFocus();
		}
		return Control::PreNotify(rEvt);
	}

	//==================================================================
	//= CheckBoxCellController
	//==================================================================
	//------------------------------------------------------------------
	sal_Bool CheckBoxCellController::WantMouseEvent() const
	{
		return sal_True;
	}

	//------------------------------------------------------------------
	CheckBox& CheckBoxCellController::GetCheckBox() const
	{
		return ((CheckBoxControl &)GetWindow()).GetBox();
	}

	//------------------------------------------------------------------
	sal_Bool CheckBoxCellController::IsModified() const
	{
		return GetCheckBox().GetSavedValue() != GetCheckBox().GetState();
	}

	//------------------------------------------------------------------
	void CheckBoxCellController::ClearModified()
	{
		GetCheckBox().SaveValue();
	}

	//------------------------------------------------------------------
	void CheckBoxCellController::SetModifyHdl(const Link& rLink)
	{
		((CheckBoxControl &)GetWindow()).SetModifyHdl(rLink);
	}

	//==================================================================
	//= MultiLineEditImplementation
	//==================================================================
	//------------------------------------------------------------------
    String MultiLineEditImplementation::GetText( LineEnd aSeparator ) const
    {
        return const_cast< MultiLineEditImplementation* >( this )->GetEditWindow().GetText( aSeparator );
    }

	//------------------------------------------------------------------
    String MultiLineEditImplementation::GetSelected( LineEnd aSeparator ) const
    {
        return const_cast< MultiLineEditImplementation* >( this )->GetEditWindow().GetSelected( aSeparator );
    }

	//==================================================================
	//= EditCellController
	//==================================================================
	//------------------------------------------------------------------
	EditCellController::EditCellController( Edit* _pEdit )
        :CellController( _pEdit )
        ,m_pEditImplementation( new EditImplementation( *_pEdit ) )
        ,m_bOwnImplementation( sal_True )
	{
	}

	//------------------------------------------------------------------
	EditCellController::EditCellController( MultiLineTextCell* _pEdit )
        :CellController( _pEdit )
        ,m_pEditImplementation( new MultiLineEditImplementation( *_pEdit ) )
        ,m_bOwnImplementation( sal_True )
	{
	}

	//------------------------------------------------------------------
	EditCellController::EditCellController( IEditImplementation* _pImplementation )
        :CellController( &_pImplementation->GetControl() )
        ,m_pEditImplementation( _pImplementation )
        ,m_bOwnImplementation( sal_False )
	{
	}

	//-----------------------------------------------------------------------------
    EditCellController::~EditCellController( )
    {
        if ( m_bOwnImplementation )
            DELETEZ( m_pEditImplementation );
    }

	//-----------------------------------------------------------------------------
	void EditCellController::SetModified()
	{
		m_pEditImplementation->SetModified();
	}

	//-----------------------------------------------------------------------------
	void EditCellController::ClearModified()
	{
		m_pEditImplementation->ClearModified();
	}

	//------------------------------------------------------------------
	sal_Bool EditCellController::MoveAllowed(const KeyEvent& rEvt) const
	{
		sal_Bool bResult;
		switch (rEvt.GetKeyCode().GetCode())
		{
			case KEY_END:
			case KEY_RIGHT:
			{
				Selection aSel = m_pEditImplementation->GetSelection();
				bResult = !aSel && aSel.Max() == m_pEditImplementation->GetText( LINEEND_LF ).Len();
			}	break;
			case KEY_HOME:
			case KEY_LEFT:
			{
				Selection aSel = m_pEditImplementation->GetSelection();
				bResult = !aSel && aSel.Min() == 0;
			}	break;
			default:
				bResult = sal_True;
		}
		return bResult;
	}

	//------------------------------------------------------------------
	sal_Bool EditCellController::IsModified() const
	{
		return m_pEditImplementation->IsModified();
	}

	//------------------------------------------------------------------
	void EditCellController::SetModifyHdl(const Link& rLink)
	{
		m_pEditImplementation->SetModifyHdl(rLink);
	}

	//==================================================================
	//= SpinCellController
	//==================================================================
	//------------------------------------------------------------------
	SpinCellController::SpinCellController(SpinField* pWin)
						 :CellController(pWin)
	{
	}

	//-----------------------------------------------------------------------------
	void SpinCellController::SetModified()
	{
		GetSpinWindow().SetModifyFlag();
	}

	//-----------------------------------------------------------------------------
	void SpinCellController::ClearModified()
	{
		GetSpinWindow().ClearModifyFlag();
	}

	//------------------------------------------------------------------
	sal_Bool SpinCellController::MoveAllowed(const KeyEvent& rEvt) const
	{
		sal_Bool bResult;
		switch (rEvt.GetKeyCode().GetCode())
		{
			case KEY_END:
			case KEY_RIGHT:
			{
				Selection aSel = GetSpinWindow().GetSelection();
				bResult = !aSel && aSel.Max() == GetSpinWindow().GetText().Len();
			}	break;
			case KEY_HOME:
			case KEY_LEFT:
			{
				Selection aSel = GetSpinWindow().GetSelection();
				bResult = !aSel && aSel.Min() == 0;
			}	break;
			default:
				bResult = sal_True;
		}
		return bResult;
	}

	//------------------------------------------------------------------
	sal_Bool SpinCellController::IsModified() const
	{
		return GetSpinWindow().IsModified();
	}

	//------------------------------------------------------------------
	void SpinCellController::SetModifyHdl(const Link& rLink)
	{
		GetSpinWindow().SetModifyHdl(rLink);
	}

	//==================================================================
	//= FormattedFieldCellController
	//==================================================================
	//------------------------------------------------------------------
	FormattedFieldCellController::FormattedFieldCellController( FormattedField* _pFormatted )
		:EditCellController( _pFormatted )
	{
	}

	//------------------------------------------------------------------
	void FormattedFieldCellController::CommitModifications()
	{
		static_cast< FormattedField& >( GetWindow() ).Commit();
	}

	//==================================================================
	//= MultiLineTextCell
	//==================================================================
	//------------------------------------------------------------------
    void MultiLineTextCell::Modify()
    {
        GetTextEngine()->SetModified( sal_True );
        MultiLineEdit::Modify();
    }

	//------------------------------------------------------------------
    sal_Bool MultiLineTextCell::dispatchKeyEvent( const KeyEvent& _rEvent )
    {
        Selection aOldSelection( GetSelection() );

        sal_Bool bWasModified = IsModified();
        ClearModifyFlag( );

        sal_Bool bHandled = GetTextView()->KeyInput( _rEvent );

        sal_Bool bIsModified = IsModified();
        if ( bWasModified && !bIsModified )
            // not sure whether this can really happen
            SetModifyFlag();

        if ( bHandled ) // the view claimed it handled the key input
        {
            // unfortunately, KeyInput also returns <TRUE/> (means "I handled this key input")
            // when nothing really changed. Let's care for this.
            Selection aNewSelection( GetSelection() );
            if  (  aNewSelection != aOldSelection   // selection changed
                || bIsModified                      // or some other modification
                )
                return sal_True;
        }
        return sal_False;
    }

	//------------------------------------------------------------------
    long MultiLineTextCell::PreNotify( NotifyEvent& rNEvt )
    {
        if ( rNEvt.GetType() == EVENT_KEYINPUT )
        {
            if ( IsWindowOrChild( rNEvt.GetWindow() ) )
            {
                // give the text view a chance to handle the keys
                // this is necessary since a lot of keys which are normally handled
                // by this view (in KeyInput) are intercepted by the EditBrowseBox,
                // which uses them for other reasons. An example is the KeyUp key,
                // which is used by both the text view and the edit browse box

                const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
                const KeyCode&  rKeyCode  = pKeyEvent->GetKeyCode();
                sal_uInt16 nCode = rKeyCode.GetCode();

                if ( ( nCode == KEY_RETURN ) && ( rKeyCode.GetModifier() == KEY_MOD1 ) )
                {
                    KeyEvent aEvent( pKeyEvent->GetCharCode(),
                        KeyCode( KEY_RETURN ),
                        pKeyEvent->GetRepeat()
                    );
                    if ( dispatchKeyEvent( aEvent ) )
                        return 1;
                }

                if ( ( nCode != KEY_TAB ) && ( nCode != KEY_RETURN ) )   // everything but tab and enter
                {
                    if ( dispatchKeyEvent( *pKeyEvent ) )
                        return 1;
                }
            }
        }
        return MultiLineEdit::PreNotify( rNEvt );
    }

// .......................................................................
}	// namespace svt
// .......................................................................


