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


#include <rtl/logfile.hxx>
#include <svl/eitem.hxx>
#include <sfx2/app.hxx>
#include <svl/intitem.hxx>
#include <svtools/imgdef.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/imgmgr.hxx>
#include <vcl/wrkwin.hxx>
#include "toolbox.hxx"
#ifndef _STARMATH_HRC
#include "starmath.hrc"
#endif
#ifndef _TOOLBOX_HRC_
#include "toolbox.hrc"
#endif
#include "view.hxx"


////////////////////////////////////////////////////////////

static sal_uInt16  GetImageListRID( sal_uInt16 nCategoryRID, sal_Bool bHighContrast )
{
    sal_uInt16 nRes = 0xFFFF;
    switch (nCategoryRID)
    {
        case RID_UNBINOPS_CAT       : nRes = RID_IL_UNBINOPS; break;
        case RID_RELATIONS_CAT      : nRes = RID_IL_RELATIONS; break;
        case RID_SETOPERATIONS_CAT  : nRes = RID_IL_SETOPERATIONS; break;
        case RID_FUNCTIONS_CAT      : nRes = RID_IL_FUNCTIONS; break;
        case RID_OPERATORS_CAT      : nRes = RID_IL_OPERATORS; break;
        case RID_ATTRIBUTES_CAT     : nRes = RID_IL_ATTRIBUTES; break;
        case RID_BRACKETS_CAT       : nRes = RID_IL_BRACKETS; break;
        case RID_FORMAT_CAT         : nRes = RID_IL_FORMAT; break;
        case RID_MISC_CAT           : nRes = RID_IL_MISC; break;
        default :
            DBG_ERROR( "unknown category" );
    }
    if (nRes != 0xFFFF && bHighContrast)
        ++nRes;     //! the resource ID for the high contrast image list is just +1 compared to the regular ones
    return nRes;
}


static sal_Int16  GetToolBoxCategoriesIndex( sal_uInt16 nCategoryRID )
{
    sal_Int16 nIdx = -1;
    switch (nCategoryRID)
    {
        case RID_UNBINOPS_CAT       : nIdx = 0; break;
        case RID_RELATIONS_CAT      : nIdx = 1; break;
        case RID_SETOPERATIONS_CAT  : nIdx = 2; break;
        case RID_FUNCTIONS_CAT      : nIdx = 3; break;
        case RID_OPERATORS_CAT      : nIdx = 4; break;
        case RID_ATTRIBUTES_CAT     : nIdx = 5; break;
        case RID_BRACKETS_CAT       : nIdx = 6; break;
        case RID_FORMAT_CAT         : nIdx = 7; break;
        case RID_MISC_CAT           : nIdx = 8; break;
        default:
			;
    }
    return nIdx;
}


static sal_uInt16  GetCategoryRID( sal_uInt16 nResId )
{
    sal_uInt16 nRes = 0xFFFF;
    switch (nResId)
    {
        case RID_IL_UNBINOPS        :
        case RID_ILH_UNBINOPS       : nRes = RID_UNBINOPS_CAT; break;
        case RID_IL_RELATIONS       :
        case RID_ILH_RELATIONS      : nRes = RID_RELATIONS_CAT; break;
        case RID_IL_SETOPERATIONS   :
        case RID_ILH_SETOPERATIONS  : nRes = RID_SETOPERATIONS_CAT; break;
        case RID_IL_FUNCTIONS       :
        case RID_ILH_FUNCTIONS      : nRes = RID_FUNCTIONS_CAT; break;
        case RID_IL_OPERATORS       :
        case RID_ILH_OPERATORS      : nRes = RID_OPERATORS_CAT; break;
        case RID_IL_ATTRIBUTES      :
        case RID_ILH_ATTRIBUTES     : nRes = RID_ATTRIBUTES_CAT; break;
        case RID_IL_BRACKETS        :
        case RID_ILH_BRACKETS       : nRes = RID_BRACKETS_CAT; break;
        case RID_IL_FORMAT          :
        case RID_ILH_FORMAT         : nRes = RID_FORMAT_CAT; break;
        case RID_IL_MISC            :
        case RID_ILH_MISC           : nRes = RID_MISC_CAT; break;
        default :
            if (nResId != RID_IL_CATALOG  &&  nResId != RID_ILH_CATALOG)
            {
#if OSL_DEBUG_LEVEL > 1
                DBG_ERROR( "unknown category" );
#endif
            }
    }
    return nRes;
}


////////////////////////////////////////////////////////////


SmToolBoxWindow::SmToolBoxWindow(SfxBindings *pTmpBindings,
								 SfxChildWindow *pChildWindow,
								 Window *pParent) :
    SfxFloatingWindow(pTmpBindings, pChildWindow, pParent, SmResId(RID_TOOLBOXWINDOW)),
    aToolBoxCat(this, SmResId(TOOLBOX_CATALOG)),
    aToolBoxCat_Delim(this, SmResId( FL_TOOLBOX_CAT_DELIM ))
{
    RTL_LOGFILE_CONTEXT( aLog, "starmath: SmToolBoxWindow::SmToolBoxWindow" );

    // allow for cursor travelling between toolbox and sub-categories
    SetStyle( GetStyle() | WB_DIALOGCONTROL );

    nActiveCategoryRID = USHRT_MAX;
    
    aToolBoxCat.SetClickHdl(LINK(this, SmToolBoxWindow, CategoryClickHdl));

    sal_uInt16 i;
    for (i = 0;  i < NUM_TBX_CATEGORIES;  ++i)
	{
		ToolBox *pBox = new ToolBox(this, SmResId( TOOLBOX_CAT_A + i ));
		vToolBoxCategories[i] = pBox;
		pBox->SetSelectHdl(LINK(this, SmToolBoxWindow, CmdSelectHdl));
	}
    pToolBoxCmd = vToolBoxCategories[0];

    for (i = 0;  i <= NUM_TBX_CATEGORIES; ++i)
    {
        aImageLists [i] = 0;
        aImageListsH[i] = 0;
    }

	FreeResource();
}

SmToolBoxWindow::~SmToolBoxWindow()
{
    int i;
    for (i = 0;  i < NUM_TBX_CATEGORIES;  ++i)
	{
		ToolBox *pBox = vToolBoxCategories[i];
		delete pBox;
	}
    for (i = 0;  i < NUM_TBX_CATEGORIES + 1;  ++i)
	{
        delete aImageLists[i];
        delete aImageListsH[i];
	}
}


SmViewShell * SmToolBoxWindow::GetView()
{
    SfxViewShell *pView = GetBindings().GetDispatcher()->GetFrame()->GetViewShell();
    return dynamic_cast< SmViewShell* >( pView);
}


const ImageList * SmToolBoxWindow::GetImageList( sal_uInt16 nResId, sal_Bool bHighContrast )
{
    // creates the image list via its resource id and stores that
    // list for later use in the respective array.

    const ImageList *pIL = 0;
    
    // get index to use
    sal_uInt16 nCategoryRID = GetCategoryRID( nResId );
    sal_Int16 nIndex = GetToolBoxCategoriesIndex( nCategoryRID );
    if (nIndex == -1 && (nResId == RID_IL_CATALOG || nResId == RID_ILH_CATALOG))
        nIndex = NUM_TBX_CATEGORIES;

    if (nIndex >= 0)
    {
        ImageList **pImgList = bHighContrast ? aImageListsH : aImageLists;
        if (!pImgList[ nIndex ])
            pImgList[ nIndex ] = new ImageList( SmResId(nResId) );
        pIL = pImgList[ nIndex ];
    }

    DBG_ASSERT( pIL, "image list not found!" );
    return pIL;
}


void SmToolBoxWindow::ApplyImageLists( sal_uInt16 nCategoryRID )
{
    sal_Bool bHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
        
    // set image list for toolbox 'catalog'
	const ImageList *pImageList = GetImageList( bHighContrast ? RID_ILH_CATALOG : RID_IL_CATALOG, bHighContrast );
    DBG_ASSERT( pImageList, "image list missing" );
    if (pImageList)
        aToolBoxCat.SetImageList( *pImageList );
        
    // set image list for active (visible) category of 'catalog'
    sal_Int16 nIdx = GetToolBoxCategoriesIndex( nCategoryRID );
    sal_uInt16 nResId = GetImageListRID( nCategoryRID, bHighContrast );
    pImageList = GetImageList( nResId, bHighContrast );
    DBG_ASSERT( pImageList && nIdx >= 0, "image list or index missing" );
    if (pImageList && nIdx >= 0)
        vToolBoxCategories[ nIdx ]->SetImageList( *pImageList );
}

void SmToolBoxWindow::DataChanged( const DataChangedEvent &rEvt )
{
    if ( (rEvt.GetType() == DATACHANGED_SETTINGS) && (rEvt.GetFlags() & SETTINGS_STYLE) )
        ApplyImageLists( nActiveCategoryRID );

    SfxFloatingWindow::DataChanged( rEvt );
}

void SmToolBoxWindow::StateChanged( StateChangedType nStateChange )
{
    static sal_Bool bSetPosition = sal_True;
    if (STATE_CHANGE_INITSHOW == nStateChange)
    {
        SetCategory( nActiveCategoryRID == USHRT_MAX ? RID_UNBINOPS_CAT : nActiveCategoryRID );

        // calculate initial position to be used after creation of the window...
        AdjustPosSize( bSetPosition );
        bSetPosition = sal_False;
    }
    //... otherwise the base class will remember the last position of the window
    SfxFloatingWindow::StateChanged( nStateChange );
}


void SmToolBoxWindow::AdjustPosSize( sal_Bool bSetPos )
{
    Size aCatSize( aToolBoxCat.CalcWindowSizePixel( 2 ) );
    Size aCmdSize( pToolBoxCmd->CalcWindowSizePixel( 4 /* see nLines in SetCategory*/ ) );
    DBG_ASSERT( aCatSize.Width() == aCmdSize.Width(), "width mismatch" );

    // catalog settings
    aToolBoxCat.SetPosPixel( Point(0, 3) );
    aToolBoxCat.SetSizePixel( aCatSize );
    // settings for catalog / category delimiter
    Point aP( aToolBoxCat_Delim.GetPosPixel() );
    aP.X() = 0;
    aToolBoxCat_Delim.SetPosPixel( aP );
    aToolBoxCat_Delim.SetSizePixel( Size( aCatSize.Width(), aToolBoxCat_Delim.GetSizePixel().Height() ) );
    // category settings
    aP.Y() += aToolBoxCat_Delim.GetSizePixel().Height();
	for (int i = 0;  i < NUM_TBX_CATEGORIES;  ++i)
    {
        vToolBoxCategories[i]->SetPosPixel( aP );
        vToolBoxCategories[i]->SetSizePixel( aCmdSize );
    }
    // main window settings
    Size    aWndSize ( aCatSize.Width(), pToolBoxCmd->GetPosPixel().Y() + pToolBoxCmd->GetSizePixel().Height() + 3);
    SetOutputSizePixel( aWndSize );

    if (bSetPos)
	{
        SmViewShell *pView = GetView();
        DBG_ASSERT( pView, "view shell missing" );
        Point aPos( 50, 75 );
        if (pView)
        {
            SmGraphicWindow &rWin = pView->GetGraphicWindow();
            aPos = Point( rWin.OutputToScreenPixel(
                            Point( rWin.GetSizePixel().Width() - aWndSize.Width(), 0) ) );
        }
		if (aPos.X() < 0)
			aPos.X() = 0;
		if (aPos.Y() < 0)
			aPos.Y() = 0;
        SetPosPixel( aPos );
	}
}


sal_Bool SmToolBoxWindow::Close()
{
    SmViewShell *pViewSh = GetView();
	if (pViewSh)
		pViewSh->GetViewFrame()->GetDispatcher()->Execute(
				SID_TOOLBOX, SFX_CALLMODE_STANDARD,
				new SfxBoolItem(SID_TOOLBOX, sal_False), 0L);
	return sal_True;
}

void SmToolBoxWindow::GetFocus()
{
    // give focus to category toolbox
    // (allow for cursor travelling when a category is selected with the mouse)
    aToolBoxCat.GrabFocus();
}

void SmToolBoxWindow::SetCategory(sal_uInt16 nCategoryRID)
{
    if (nCategoryRID != nActiveCategoryRID)
        ApplyImageLists( nCategoryRID );

    sal_uInt16 nLines;
	// check for valid resource id
    switch (nCategoryRID)
	{
        case RID_UNBINOPS_CAT :     nLines = 4; break;
        case RID_RELATIONS_CAT:     nLines = 4; break;
        case RID_SETOPERATIONS_CAT: nLines = 4; break;
        case RID_FUNCTIONS_CAT:     nLines = 4; break;
        case RID_OPERATORS_CAT:     nLines = 3; break;
        case RID_ATTRIBUTES_CAT:    nLines = 4; break;
        case RID_MISC_CAT:          nLines = 4; break;
        case RID_BRACKETS_CAT:      nLines = 4; break;
        case RID_FORMAT_CAT:        nLines = 3; break;
		default:
			// nothing to be done
			return;
	}

    pToolBoxCmd->Hide();

    sal_Int16 nIdx = GetToolBoxCategoriesIndex( nCategoryRID );
    DBG_ASSERT( nIdx >= 0, "unknown category" );
    if (nIdx >= 0)
        pToolBoxCmd = vToolBoxCategories[nIdx];

    // calculate actual size of window to use
    Size aCatSize( aToolBoxCat.CalcWindowSizePixel( 2 ) );
    Size aCmdSize( pToolBoxCmd->CalcWindowSizePixel( nLines ) );
    DBG_ASSERT( aCatSize.Width() == aCmdSize.Width(), "width mismatch" );
    // main window settings
    Size  aWndSize ( aCatSize.Width(), pToolBoxCmd->GetPosPixel().Y() + aCmdSize.Height() + 3);
    SetOutputSizePixel( aWndSize );

    if (nActiveCategoryRID)
        aToolBoxCat.CheckItem(nActiveCategoryRID, sal_False);
    nActiveCategoryRID = nCategoryRID;
    aToolBoxCat.CheckItem(nActiveCategoryRID, sal_True);

	pToolBoxCmd->Show();
}


IMPL_LINK( SmToolBoxWindow, CategoryClickHdl, ToolBox*, pToolBox)
{
	int nItemId = pToolBox->GetCurItemId();
	if (nItemId != 0)
        SetCategory( sal::static_int_cast< sal_uInt16 >(nItemId) );
	return 0;
}


IMPL_LINK( SmToolBoxWindow, CmdSelectHdl, ToolBox*, pToolBox)
{
    SmViewShell *pViewSh = GetView();
	if (pViewSh)
		pViewSh->GetViewFrame()->GetDispatcher()->Execute(
				SID_INSERTCOMMAND, SFX_CALLMODE_STANDARD,
				new SfxInt16Item(SID_INSERTCOMMAND, pToolBox->GetCurItemId()), 0L);
	return 0;
}


/**************************************************************************/

SFX_IMPL_FLOATINGWINDOW(SmToolBoxWrapper, SID_TOOLBOXWINDOW);

SmToolBoxWrapper::SmToolBoxWrapper(Window *pParentWindow,
								   sal_uInt16 nId, SfxBindings* pBindings,
								   SfxChildWinInfo *pInfo) :
	SfxChildWindow(pParentWindow, nId)
{
    eChildAlignment = SFX_ALIGN_NOALIGNMENT;

	pWindow = new SmToolBoxWindow(pBindings, this, pParentWindow);
    ((SfxFloatingWindow *)pWindow)->Initialize(pInfo);
}


