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



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

#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/viewfrm.hxx>
#include <svl/slstitm.hxx>
#include <svl/stritem.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/svapp.hxx>
#include "navipi.hxx"
#include "popmenu.hxx"
#include "scresid.hxx"
#include "sc.hrc"
#include "globstr.hrc"

//========================================================================
// class ScScenarioWindow ------------------------------------------------
//========================================================================

ScScenarioListBox::ScScenarioListBox( ScScenarioWindow& rParent ) :
    ListBox( &rParent, WB_BORDER | WB_TABSTOP ),
    mrParent( rParent )
{
	Font aFont( GetFont() );
	aFont.SetTransparent( sal_True );
	aFont.SetWeight( WEIGHT_LIGHT );
	SetFont( aFont );
}

ScScenarioListBox::~ScScenarioListBox()
{
}

void ScScenarioListBox::UpdateEntries( List* pNewEntryList )
{
	Clear();
    maEntries.clear();

    if( !pNewEntryList )
        return;

    switch( pNewEntryList->Count() )
    {
        case 0:
            // no scenarios in current sheet
            mrParent.SetComment( EMPTY_STRING );
        break;

        case 1:
            // sheet is a scenario container, comment only
            mrParent.SetComment( *static_cast< String* >( pNewEntryList->First() ) );
        break;

        default:
        {
            // sheet contains scenarios
            DBG_ASSERT( pNewEntryList->Count() % 3 == 0, "ScScenarioListBox::UpdateEntries - wrong list size" );
            SetUpdateMode( sal_False );
            String* pEntry = static_cast< String* >( pNewEntryList->First() );
            while( pEntry )
            {
                ScenarioEntry aEntry;

                // first entry of a triple is the scenario name
                aEntry.maName = *pEntry;
                // second entry of a triple is the scenario comment
                if( (pEntry = static_cast< String* >( pNewEntryList->Next() )) != 0 )
                    aEntry.maComment = *pEntry;
                // third entry of a triple is the protection ("0" = not protected, "1" = protected)
                if( (pEntry = static_cast< String* >( pNewEntryList->Next() )) != 0 )
                    aEntry.mbProtected = (pEntry->Len() > 0) && (pEntry->GetChar( 0 ) != '0');

                maEntries.push_back( aEntry );
                InsertEntry( aEntry.maName, LISTBOX_APPEND );
                pEntry = static_cast< String* >( pNewEntryList->Next() );
            }
            SetUpdateMode( sal_True );
            SetNoSelection();
            mrParent.SetComment( EMPTY_STRING );
        }
    }
}

void ScScenarioListBox::Select()
{
    if( const ScenarioEntry* pEntry = GetSelectedEntry() )
        mrParent.SetComment( pEntry->maComment );
}

void ScScenarioListBox::DoubleClick()
{
    SelectScenario();
}

long ScScenarioListBox::Notify( NotifyEvent& rNEvt )
{
    bool bHandled = false;

    if( rNEvt.GetType() == EVENT_KEYINPUT )
    {
        KeyCode aCode = rNEvt.GetKeyEvent()->GetKeyCode();
        switch( aCode.GetCode() )
        {
            case KEY_RETURN:
                SelectScenario();
                bHandled = true;
            break;
            case KEY_DELETE:
                DeleteScenario( true );
                bHandled = true;
            break;
        }
    }
    else if ( rNEvt.GetType() == EVENT_COMMAND && GetSelectEntryCount() )
    {
        const CommandEvent* pCEvt = rNEvt.GetCommandEvent();
        if ( pCEvt && pCEvt->GetCommand() == COMMAND_CONTEXTMENU )
        {
            if( const ScenarioEntry* pEntry = GetSelectedEntry() )
            {
                if( !pEntry->mbProtected )
                {
                    ScPopupMenu aPopup( ScResId( RID_POPUP_NAVIPI_SCENARIO ) );
                    aPopup.Execute( this, pCEvt->GetMousePosPixel() );
                    if (aPopup.WasHit())
                    {
                        switch( aPopup.GetSelected() )
                        {
                            case RID_NAVIPI_SCENARIO_DELETE:
                                DeleteScenario( true );
                            break;
                            case RID_NAVIPI_SCENARIO_EDIT:
                                EditScenario();
                            break;
                        }
                    }
                }
            }
            bHandled = true;
        }
    }

    return bHandled ? 1 : ListBox::Notify( rNEvt );
}

const ScScenarioListBox::ScenarioEntry* ScScenarioListBox::GetSelectedEntry() const
{
    size_t nPos = GetSelectEntryPos();
    return (nPos < maEntries.size()) ? &maEntries[ nPos ] : 0;
}

void ScScenarioListBox::ExecuteScenarioSlot( sal_uInt16 nSlotId )
{
    if( SfxViewFrame* pViewFrm = SfxViewFrame::Current() )
    {
        SfxStringItem aStringItem( nSlotId, GetSelectEntry() );
        pViewFrm->GetDispatcher()->Execute( nSlotId, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, &aStringItem, 0L, 0L );
    }
}

void ScScenarioListBox::SelectScenario()
{
    if( GetSelectEntryCount() > 0 )
        ExecuteScenarioSlot( SID_SELECT_SCENARIO );
}

void ScScenarioListBox::EditScenario()
{
    if( GetSelectEntryCount() > 0 )
        ExecuteScenarioSlot( SID_EDIT_SCENARIO );
}

void ScScenarioListBox::DeleteScenario( bool bQueryBox )
{
    if( GetSelectEntryCount() > 0 )
        if( !bQueryBox || (::QueryBox( 0, WinBits( WB_YES_NO | WB_DEF_YES ), ScGlobal::GetRscString( STR_QUERY_DELSCENARIO ) ).Execute() == RET_YES) )
            ExecuteScenarioSlot( SID_DELETE_SCENARIO );
}

//========================================================================
// class ScScenarioWindow ------------------------------------------------
//========================================================================

ScScenarioWindow::ScScenarioWindow( Window* pParent,const String& aQH_List,
									const String& aQH_Comment)
    :   Window      ( pParent, WB_TABSTOP | WB_DIALOGCONTROL ),
        aLbScenario ( *this ),
        aEdComment  ( this,  WB_BORDER | WB_LEFT | WB_READONLY | WB_VSCROLL | WB_TABSTOP )
{
	Font aFont( GetFont() );
	aFont.SetTransparent( sal_True );
	aFont.SetWeight( WEIGHT_LIGHT );
	aEdComment.SetFont( aFont );
	aEdComment.SetMaxTextLen( 512 );
	aLbScenario.SetPosPixel( Point(0,0) );
	aLbScenario.SetHelpId(HID_SC_SCENWIN_TOP);
	aEdComment.SetHelpId(HID_SC_SCENWIN_BOTTOM);
	aLbScenario.Show();
	aEdComment.Show();

	aLbScenario.SetQuickHelpText(aQH_List);
	aEdComment.SetQuickHelpText(aQH_Comment);
	aEdComment.SetBackground( Color( COL_LIGHTGRAY ) );

	SfxViewFrame* pViewFrm = SfxViewFrame::Current();
	if (pViewFrm)
	{
		SfxBindings& rBindings = pViewFrm->GetBindings();
		rBindings.Invalidate( SID_SELECT_SCENARIO );
		rBindings.Update( SID_SELECT_SCENARIO );
	}
}

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

ScScenarioWindow::~ScScenarioWindow()
{
}

void ScScenarioWindow::Paint( const Rectangle& rRec )
{
	const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
	Color aBgColor = rStyleSettings.GetFaceColor();

	SetBackground( aBgColor );

	Window::Paint( rRec );
}

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

void ScScenarioWindow::NotifyState( const SfxPoolItem* pState )
{
	if( pState )
	{
		aLbScenario.Enable();

		if ( dynamic_cast< const SfxStringItem* >(pState) )
		{
			String aNewEntry( ((const SfxStringItem*)pState)->GetValue() );

			if ( aNewEntry.Len() > 0 )
				aLbScenario.SelectEntry( aNewEntry );
			else
				aLbScenario.SetNoSelection();
		}
		else if ( dynamic_cast< const SfxStringListItem* >(pState) )
		{
			aLbScenario.UpdateEntries( ((SfxStringListItem*)pState)->GetList() );
		}
	}
	else
	{
		aLbScenario.Disable();
		aLbScenario.SetNoSelection();
	}
}

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

void ScScenarioWindow::SetSizePixel( const Size& rNewSize )
{
	Size aSize( rNewSize );
	long nHeight = aSize.Height() / 2;

	Window::SetSizePixel( aSize );

	aSize.Height() = nHeight;
	aLbScenario.SetSizePixel( aSize );

	aSize.Height() -= 4;
	aEdComment.SetPosSizePixel(	Point( 0, nHeight+4 ), aSize );
}




