/**************************************************************
 * 
 * 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 "solveroptions.hxx"
#include "solveroptions.hrc"
#include "scresid.hxx"
#include "global.hxx"
#include "miscuno.hxx"
#include "solverutil.hxx"

#include <rtl/math.hxx>
#include <vcl/msgbox.hxx>
#include <unotools/collatorwrapper.hxx>
#include <unotools/localedatawrapper.hxx>

#include <algorithm>

#include <com/sun/star/sheet/Solver.hpp>
#include <com/sun/star/sheet/XSolverDescription.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>

using namespace com::sun::star;

//==================================================================

/// Helper for sorting properties
struct ScSolverOptionsEntry
{
    sal_Int32       nPosition;
    rtl::OUString   aDescription;

    ScSolverOptionsEntry() : nPosition(0) {}

    bool operator< (const ScSolverOptionsEntry& rOther) const
    {
        return ( ScGlobal::GetCollator()->compareString( aDescription, rOther.aDescription ) == COMPARE_LESS );
    }
};

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

class ScSolverOptionsString : public SvLBoxString
{
    bool        mbIsDouble;
    double      mfDoubleValue;
    sal_Int32   mnIntValue;

public:
    ScSolverOptionsString( SvLBoxEntry* pEntry, sal_uInt16 nFlags, const String& rStr ) :
        SvLBoxString( pEntry, nFlags, rStr ),
        mbIsDouble( false ),
        mfDoubleValue( 0.0 ),
        mnIntValue( 0 ) {}

    bool      IsDouble() const        { return mbIsDouble; }
    double    GetDoubleValue() const  { return mfDoubleValue; }
    sal_Int32 GetIntValue() const     { return mnIntValue; }

    void      SetDoubleValue( double fNew ) { mbIsDouble = true; mfDoubleValue = fNew; }
    void      SetIntValue( sal_Int32 nNew ) { mbIsDouble = false; mnIntValue = nNew; }
// MT: Commented out SV_ITEM_ID_EXTENDRLBOXSTRING and GetExtendText() in svlbitem.hxx - needed?
//	virtual USHORT IsA() {return SV_ITEM_ID_EXTENDRLBOXSTRING;}
//	virtual XubString GetExtendText() const;
    virtual void Paint( const Point& rPos, SvLBox& rDev, sal_uInt16 nFlags, SvLBoxEntry* pEntry );
};

// MT: Commented out SV_ITEM_ID_EXTENDRLBOXSTRING and GetExtendText() in svlbitem.hxx - needed?
/*
XubString ScSolverOptionsString::GetExtendText() const
{
	String aNormalStr( GetText() );
	aNormalStr.Append( (sal_Unicode) ':' );
	String sTxt( ' ' );
    if ( mbIsDouble )
        sTxt += (String)rtl::math::doubleToUString( mfDoubleValue,
            rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
            ScGlobal::GetpLocaleData()->getNumDecimalSep().GetChar(0), true );
    else
        sTxt += String::CreateFromInt32( mnIntValue );
	aNormalStr.Append(sTxt);
	return aNormalStr;
}
*/

void ScSolverOptionsString::Paint( const Point& rPos, SvLBox& rDev, sal_uInt16, SvLBoxEntry* /* pEntry */ )
{
    //! move position? (SvxLinguTabPage: aPos.X() += 20)
    String aNormalStr( GetText() );
    aNormalStr.Append( (sal_Unicode) ':' );
    rDev.DrawText( rPos, aNormalStr );

    Point aNewPos( rPos );
    aNewPos.X() += rDev.GetTextWidth( aNormalStr );
    Font aOldFont( rDev.GetFont() );
    Font aFont( aOldFont );
    aFont.SetWeight( WEIGHT_BOLD );

    String sTxt( ' ' );
    if ( mbIsDouble )
        sTxt += (String)rtl::math::doubleToUString( mfDoubleValue,
            rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
            ScGlobal::GetpLocaleData()->getNumDecimalSep().GetChar(0), true );
    else
        sTxt += String::CreateFromInt32( mnIntValue );
    rDev.SetFont( aFont );
    rDev.DrawText( aNewPos, sTxt );

    rDev.SetFont( aOldFont );
}

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

ScSolverOptionsDialog::ScSolverOptionsDialog( Window* pParent,
                        const uno::Sequence<rtl::OUString>& rImplNames,
                        const uno::Sequence<rtl::OUString>& rDescriptions,
                        const String& rEngine,
                        const uno::Sequence<beans::PropertyValue>& rProperties )
    : ModalDialog( pParent, ScResId( RID_SCDLG_SOLVEROPTIONS ) ),
    maFtEngine      ( this, ScResId( FT_ENGINE ) ),
    maLbEngine      ( this, ScResId( LB_ENGINE ) ),
    maFtSettings    ( this, ScResId( FT_SETTINGS ) ),
    maLbSettings    ( this, ScResId( LB_SETTINGS ) ),
    maBtnEdit       ( this, ScResId( BTN_EDIT ) ),
    maFlButtons     ( this, ScResId( FL_BUTTONS ) ),
    maBtnHelp       ( this, ScResId( BTN_HELP ) ),
    maBtnOk         ( this, ScResId( BTN_OK ) ),
    maBtnCancel     ( this, ScResId( BTN_CANCEL ) ),
    mpCheckButtonData( NULL ),
    maImplNames( rImplNames ),
    maDescriptions( rDescriptions ),
    maEngine( rEngine ),
    maProperties( rProperties )
{
    maLbEngine.SetSelectHdl( LINK( this, ScSolverOptionsDialog, EngineSelectHdl ) );

	maBtnEdit.SetClickHdl( LINK( this, ScSolverOptionsDialog, ButtonHdl ) );

    maLbSettings.SetStyle( maLbSettings.GetStyle()|WB_CLIPCHILDREN|WB_FORCE_MAKEVISIBLE );
    maLbSettings.SetHelpId( HID_SC_SOLVEROPTIONS_LB );
    maLbSettings.SetHighlightRange();

    maLbSettings.SetSelectHdl( LINK( this, ScSolverOptionsDialog, SettingsSelHdl ) );
    maLbSettings.SetDoubleClickHdl( LINK( this, ScSolverOptionsDialog, SettingsDoubleClickHdl ) );

    sal_Int32 nSelect = -1;
    sal_Int32 nImplCount = maImplNames.getLength();
    for (sal_Int32 nImpl=0; nImpl<nImplCount; ++nImpl)
    {
        String aImplName( maImplNames[nImpl] );
        String aDescription( maDescriptions[nImpl] );   // user-visible descriptions in list box
        maLbEngine.InsertEntry( aDescription );
        if ( aImplName == maEngine )
            nSelect = nImpl;
    }
    if ( nSelect < 0 )                  // no (valid) engine given
    {
        if ( nImplCount > 0 )
        {
            maEngine = maImplNames[0];  // use first implementation
            nSelect = 0;
        }
        else
            maEngine.Erase();
        maProperties.realloc(0);        // don't use options from different engine
    }
    if ( nSelect >= 0 )                 // select in list box
        maLbEngine.SelectEntryPos( static_cast<sal_uInt16>(nSelect) );

    if ( !maProperties.getLength() )
        ReadFromComponent();            // fill maProperties from component (using maEngine)
    FillListBox();                      // using maProperties

    FreeResource();
}

ScSolverOptionsDialog::~ScSolverOptionsDialog()
{
    delete mpCheckButtonData;
}

const String& ScSolverOptionsDialog::GetEngine() const
{
    return maEngine;    // already updated in selection handler
}

const uno::Sequence<beans::PropertyValue>& ScSolverOptionsDialog::GetProperties()
{
    // update maProperties from list box content
    // order of entries in list box and maProperties is the same
    sal_Int32 nEntryCount = maProperties.getLength();
    SvLBoxTreeList* pModel = maLbSettings.GetModel();
    if ( nEntryCount == (sal_Int32)pModel->GetEntryCount() )
    {
        for (sal_Int32 nEntryPos=0; nEntryPos<nEntryCount; ++nEntryPos)
        {
            uno::Any& rValue = maProperties[nEntryPos].Value;
            SvLBoxEntry* pEntry = pModel->GetEntry(nEntryPos);

            bool bHasData = false;
            sal_uInt16 nItemCount = pEntry->ItemCount();
            for (sal_uInt16 nItemPos=0; nItemPos<nItemCount && !bHasData; ++nItemPos)
            {
                SvLBoxItem*	pItem = pEntry->GetItem( nItemPos );
                ScSolverOptionsString* pStringItem = dynamic_cast<ScSolverOptionsString*>(pItem);
                if ( pStringItem )
                {
                    if ( pStringItem->IsDouble() )
                        rValue <<= pStringItem->GetDoubleValue();
                    else
                        rValue <<= pStringItem->GetIntValue();
                    bHasData = true;
                }
            }
            if ( !bHasData )
                ScUnoHelpFunctions::SetBoolInAny( rValue,
                                    maLbSettings.GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED );
        }
    }
    else
    {
        DBG_ERRORFILE( "wrong count" );
    }
    
    return maProperties;
}

void ScSolverOptionsDialog::FillListBox()
{
    // get property descriptions, sort by them

    uno::Reference<sheet::XSolverDescription> xDesc( ScSolverUtil::GetSolver( maEngine ), uno::UNO_QUERY );
    sal_Int32 nCount = maProperties.getLength();
    std::vector<ScSolverOptionsEntry> aDescriptions( nCount );
    for (sal_Int32 nPos=0; nPos<nCount; nPos++)
    {
        rtl::OUString aPropName( maProperties[nPos].Name );
        rtl::OUString aVisName;
        if ( xDesc.is() )
            aVisName = xDesc->getPropertyDescription( aPropName );
        if ( !aVisName.getLength() )
            aVisName = aPropName;
        aDescriptions[nPos].nPosition = nPos;
        aDescriptions[nPos].aDescription = aVisName;
    }
    std::sort( aDescriptions.begin(), aDescriptions.end() );

    // also update maProperties to the order of descriptions

    uno::Sequence<beans::PropertyValue> aNewSeq;
    aNewSeq.realloc( nCount );
    for (sal_Int32 nPos=0; nPos<nCount; nPos++)
        aNewSeq[nPos] = maProperties[ aDescriptions[nPos].nPosition ];
    maProperties = aNewSeq;

    // fill the list box

    maLbSettings.SetUpdateMode(sal_False);
    maLbSettings.Clear();

    String sEmpty;
    if (!mpCheckButtonData)
        mpCheckButtonData = new SvLBoxButtonData( &maLbSettings );

    SvLBoxTreeList* pModel = maLbSettings.GetModel();
    SvLBoxEntry* pEntry = NULL;

    for (sal_Int32 nPos=0; nPos<nCount; nPos++)
    {
        rtl::OUString aVisName = aDescriptions[nPos].aDescription;
            
        uno::Any aValue = maProperties[nPos].Value;
        uno::TypeClass eClass = aValue.getValueTypeClass();
        if ( eClass == uno::TypeClass_BOOLEAN )
        {
            // check box entry
            pEntry = new SvLBoxEntry;
            SvLBoxButton* pButton = new SvLBoxButton( pEntry, SvLBoxButtonKind_enabledCheckbox, 0, mpCheckButtonData );
            if ( ScUnoHelpFunctions::GetBoolFromAny( aValue ) )
                pButton->SetStateChecked();
            else
                pButton->SetStateUnchecked();
            pEntry->AddItem( pButton );
            pEntry->AddItem( new SvLBoxContextBmp( pEntry, 0, Image(), Image(), 0 ) );
            pEntry->AddItem( new SvLBoxString( pEntry, 0, aVisName ) );
        }
        else
        {
            // value entry
            pEntry = new SvLBoxEntry;
            pEntry->AddItem( new SvLBoxString( pEntry, 0, sEmpty ) );                   // empty column
            pEntry->AddItem( new SvLBoxContextBmp( pEntry, 0, Image(), Image(), 0 ) );
            ScSolverOptionsString* pItem = new ScSolverOptionsString( pEntry, 0, aVisName );
            if ( eClass == uno::TypeClass_DOUBLE )
            {
                double fDoubleValue = 0.0;
                if ( aValue >>= fDoubleValue )
                    pItem->SetDoubleValue( fDoubleValue );
            }
            else
            {
                sal_Int32 nIntValue = 0;
                if ( aValue >>= nIntValue )
                    pItem->SetIntValue( nIntValue );
            }
            pEntry->AddItem( pItem );
        }
        pModel->Insert( pEntry );
    }

    maLbSettings.SetUpdateMode(sal_True);
}

void ScSolverOptionsDialog::ReadFromComponent()
{
    maProperties = ScSolverUtil::GetDefaults( maEngine );
}

void ScSolverOptionsDialog::EditOption()
{
    SvLBoxEntry* pEntry = maLbSettings.GetCurEntry();
    if (pEntry)
    {
        sal_uInt16 nItemCount = pEntry->ItemCount();
        for (sal_uInt16 nPos=0; nPos<nItemCount; ++nPos)
        {
            SvLBoxItem*	pItem = pEntry->GetItem( nPos );
            ScSolverOptionsString* pStringItem = dynamic_cast<ScSolverOptionsString*>(pItem);
            if ( pStringItem )
            {
                if ( pStringItem->IsDouble() )
                {
                    ScSolverValueDialog aValDialog( this );
                    aValDialog.SetOptionName( pStringItem->GetText() );
                    aValDialog.SetValue( pStringItem->GetDoubleValue() );
                    if ( aValDialog.Execute() == RET_OK )
                    {
                        pStringItem->SetDoubleValue( aValDialog.GetValue() );
                        maLbSettings.InvalidateEntry( pEntry );
                    }
                }
                else
                {
                    ScSolverIntegerDialog aIntDialog( this );
                    aIntDialog.SetOptionName( pStringItem->GetText() );
                    aIntDialog.SetValue( pStringItem->GetIntValue() );
                    if ( aIntDialog.Execute() == RET_OK )
                    {
                        pStringItem->SetIntValue( aIntDialog.GetValue() );
                        maLbSettings.InvalidateEntry( pEntry );
                    }
                }
            }
        }
    }
}

IMPL_LINK( ScSolverOptionsDialog, ButtonHdl, PushButton*, pBtn )
{
    if ( pBtn == &maBtnEdit )
        EditOption();

	return 0;
}

IMPL_LINK( ScSolverOptionsDialog, SettingsDoubleClickHdl, SvTreeListBox*, EMPTYARG )
{
    EditOption();
	return 0;
}

IMPL_LINK( ScSolverOptionsDialog, EngineSelectHdl, ListBox*, EMPTYARG )
{
    sal_uInt16 nSelectPos = maLbEngine.GetSelectEntryPos();
    if ( nSelectPos < maImplNames.getLength() )
    {
        String aNewEngine( maImplNames[nSelectPos] );
        if ( aNewEngine != maEngine )
        {
            maEngine = aNewEngine;
            ReadFromComponent();            // fill maProperties from component (using maEngine)
            FillListBox();                  // using maProperties
        }
    }
	return 0;
}

IMPL_LINK( ScSolverOptionsDialog, SettingsSelHdl, SvxCheckListBox*, EMPTYARG )
{
    sal_Bool bCheckbox = sal_False;

    SvLBoxEntry* pEntry = maLbSettings.GetCurEntry();
    if (pEntry)
    {
        SvLBoxItem* pItem = pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON);
        if ( pItem && pItem->IsA() == SV_ITEM_ID_LBOXBUTTON )
            bCheckbox = sal_True;
    }

    maBtnEdit.Enable( !bCheckbox );

    return 0;
}

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

ScSolverIntegerDialog::ScSolverIntegerDialog( Window * pParent )
    : ModalDialog( pParent, ScResId( RID_SCDLG_SOLVER_INTEGER ) ),
    maFtName        ( this, ScResId( FT_OPTIONNAME ) ),
    maNfValue       ( this, ScResId( NF_VALUE ) ),
    maFlButtons     ( this, ScResId( FL_BUTTONS ) ),
    maBtnOk         ( this, ScResId( BTN_OK ) ),
    maBtnCancel     ( this, ScResId( BTN_CANCEL ) )
{
    FreeResource();
}

ScSolverIntegerDialog::~ScSolverIntegerDialog()
{
}

void ScSolverIntegerDialog::SetOptionName( const String& rName )
{
    maFtName.SetText( rName );
}

void ScSolverIntegerDialog::SetValue( sal_Int32 nValue )
{
    maNfValue.SetValue( nValue );
}

sal_Int32 ScSolverIntegerDialog::GetValue() const
{
    sal_Int64 nValue = maNfValue.GetValue();
    if ( nValue < SAL_MIN_INT32 )
        return SAL_MIN_INT32;
    if ( nValue > SAL_MAX_INT32 )
        return SAL_MAX_INT32;
    return (sal_Int32) nValue;
}

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

ScSolverValueDialog::ScSolverValueDialog( Window * pParent )
    : ModalDialog( pParent, ScResId( RID_SCDLG_SOLVER_DOUBLE ) ),
    maFtName        ( this, ScResId( FT_OPTIONNAME ) ),
    maEdValue       ( this, ScResId( ED_VALUE ) ),
    maFlButtons     ( this, ScResId( FL_BUTTONS ) ),
    maBtnOk         ( this, ScResId( BTN_OK ) ),
    maBtnCancel     ( this, ScResId( BTN_CANCEL ) )
{
    FreeResource();
}

ScSolverValueDialog::~ScSolverValueDialog()
{
}

void ScSolverValueDialog::SetOptionName( const String& rName )
{
    maFtName.SetText( rName );
}

void ScSolverValueDialog::SetValue( double fValue )
{
    maEdValue.SetText( rtl::math::doubleToUString( fValue,
            rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
            ScGlobal::GetpLocaleData()->getNumDecimalSep().GetChar(0), true ) );
}

double ScSolverValueDialog::GetValue() const
{
    String aInput = maEdValue.GetText();

    const LocaleDataWrapper* pLocaleData = ScGlobal::GetpLocaleData();
    rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok;
    double fValue = rtl::math::stringToDouble( aInput,
                            pLocaleData->getNumDecimalSep().GetChar(0),
                            pLocaleData->getNumThousandSep().GetChar(0),
                            &eStatus, NULL );
    return fValue;
}

