/**************************************************************
 *
 * 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 <sfx2/sidebar/ResourceDefinitions.hrc>
#include <sfx2/sidebar/Theme.hxx>
#include <sfx2/sidebar/ControlFactory.hxx>
#include <sfx2/sidebar/Layouter.hxx>
#include <LinePropertyPanel.hxx>
#include <LinePropertyPanel.hrc>
#include <svx/dialogs.hrc>
#include <svx/dialmgr.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
#include <svx/xlnclit.hxx>
#include <svx/xtable.hxx>
#include <svx/xdash.hxx>
#include <svx/drawitem.hxx>
#include <svx/svxitems.hrc>
#include <svtools/valueset.hxx>
#include <unotools/pathoptions.hxx>
#include <unotools/viewoptions.hxx>
#include <comphelper/processfactory.hxx>
#include <i18npool/mslangid.hxx>
#include <svx/xlineit0.hxx>
#include <svx/xlndsit.hxx>
#include <vcl/svapp.hxx>
#include <svx/xlnwtit.hxx>
#include <vcl/lstbox.hxx>
#include <svx/tbxcolorupdate.hxx>
#include <vcl/toolbox.hxx>
#include <svx/xlntrit.hxx>
#include <svx/xlnstit.hxx>
#include <svx/xlnedit.hxx>
#include <svx/xlncapit.hxx>
#include <svx/xlinjoit.hxx>
#include "svx/sidebar/PopupContainer.hxx"
#include "svx/sidebar/PopupControl.hxx"
#include <svx/sidebar/ColorControl.hxx>
#include "LineWidthControl.hxx"
#include <boost/bind.hpp>

using namespace css;
using namespace cssu;
using ::sfx2::sidebar::Layouter;
using ::sfx2::sidebar::Theme;


#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))

namespace {
    short GetItemId_Impl_line( ValueSet& rValueSet, const Color& rCol )
    {
        if(rCol == COL_AUTO)
            return 0;

        bool	bFound = false;
        sal_uInt16 nCount = rValueSet.GetItemCount();
        sal_uInt16	n	   = 1;

        while ( !bFound && n <= nCount )
        {
            Color aValCol = rValueSet.GetItemColor(n);

            bFound = (   aValCol.GetRed()   == rCol.GetRed()
                && aValCol.GetGreen() == rCol.GetGreen()
                && aValCol.GetBlue()  == rCol.GetBlue() );

            if ( !bFound )
                n++;
        }
        return bFound ? n : -1;
    }

    void FillLineEndListBox(ListBox& rListBoxStart, ListBox& rListBoxEnd, const XLineEndListSharedPtr aList)
    {
        const sal_uInt32 nCount(aList.get() ? aList->Count() : 0);
        const String sNone(SVX_RES(RID_SVXSTR_NONE));

        rListBoxStart.SetUpdateMode(false);
        rListBoxEnd.SetUpdateMode(false);

        rListBoxStart.Clear();
        rListBoxEnd.Clear();

        // add 'none' entries
        rListBoxStart.InsertEntry(sNone);
        rListBoxEnd.InsertEntry(sNone);

        for(sal_uInt32 i(0); i < nCount; i++)
        {
            XLineEndEntry* pEntry = aList->GetLineEnd(i);
            const Bitmap aBitmap = aList->GetUiBitmap(i);

            if(!aBitmap.IsEmpty())
            {
                Bitmap aCopyStart(aBitmap);
                Bitmap aCopyEnd(aBitmap);
                // delete pBitmap;
                const Size aBmpSize(aCopyStart.GetSizePixel());
                const Rectangle aCropRectStart(Point(), Size(aBmpSize.Width() / 2, aBmpSize.Height()));
                const Rectangle aCropRectEnd(Point(aBmpSize.Width() / 2, 0), Size(aBmpSize.Width() / 2, aBmpSize.Height()));

                aCopyStart.Crop(aCropRectStart);
                rListBoxStart.InsertEntry(
                    pEntry->GetName(),
                    aCopyStart);

                aCopyEnd.Crop(aCropRectEnd);
                rListBoxEnd.InsertEntry(
                    pEntry->GetName(),
                    aCopyEnd);
            }
            else
            {
                rListBoxStart.InsertEntry(pEntry->GetName());
                rListBoxEnd.InsertEntry(pEntry->GetName());
            }
        }

        rListBoxStart.SetUpdateMode(true);
        rListBoxEnd.SetUpdateMode(true);
    }

    void FillLineStyleListBox(ListBox& rListBox, const XDashListSharedPtr aList)
    {
        const sal_uInt32 nCount(aList.get() ? aList->Count() : 0);
        rListBox.SetUpdateMode(false);

        rListBox.Clear();

        // entry for 'none'
        rListBox.InsertEntry(aList->GetStringForUiNoLine());

        // entry for solid line
        rListBox.InsertEntry(aList->GetStringForUiSolidLine(), aList->GetBitmapForUISolidLine());

        for(sal_uInt32 i(0); i < nCount; i++)
        {
            XDashEntry* pEntry = aList->GetDash(i);
            const Bitmap aBitmap = aList->GetUiBitmap(i);

            if(!aBitmap.IsEmpty())
            {
                rListBox.InsertEntry(
                    pEntry->GetName(),
                    aBitmap);
                // delete pBitmap;
            }
            else
            {
                rListBox.InsertEntry(pEntry->GetName());
            }
        }

        rListBox.SetUpdateMode(true);
    }
} // end of anonymous namespace

// namespace open

namespace svx { namespace sidebar {

LinePropertyPanel::LinePropertyPanel(
    Window* pParent,
    const cssu::Reference<css::frame::XFrame>& rxFrame,
    SfxBindings* pBindings)
:   Control(
        pParent,
        SVX_RES(RID_SIDEBAR_LINE_PANEL)),
    mpFTWidth(new FixedText(this, SVX_RES(FT_WIDTH))),
    mpTBWidthBackground(sfx2::sidebar::ControlFactory::CreateToolBoxBackground(this)),
    mpTBWidth(sfx2::sidebar::ControlFactory::CreateToolBox(mpTBWidthBackground.get(), SVX_RES(TB_WIDTH))),
    mpFTColor(new FixedText(this, SVX_RES(FT_COLOR))),
    mpTBColorBackground(sfx2::sidebar::ControlFactory::CreateToolBoxBackground(this)),
    mpTBColor(sfx2::sidebar::ControlFactory::CreateToolBox(mpTBColorBackground.get(), SVX_RES(TB_COLOR))),
    mpFTStyle(new FixedText(this, SVX_RES(FT_STYLE))),
    mpLBStyle(new ListBox(this, SVX_RES(LB_STYLE))),
    mpFTTrancparency(new FixedText(this, SVX_RES(FT_TRANSPARENT))),
    mpMFTransparent(new MetricField(this, SVX_RES(MF_TRANSPARENT))),
    mpFTArrow(new FixedText(this, SVX_RES(FT_ARROW))),
    mpLBStart(new ListBox(this, SVX_RES(LB_START))),
    mpLBEnd(new ListBox(this, SVX_RES(LB_END))),
    mpFTEdgeStyle(new FixedText(this, SVX_RES(FT_EDGESTYLE))),
    mpLBEdgeStyle(new ListBox(this, SVX_RES(LB_EDGESTYLE))),
    mpFTCapStyle(new FixedText(this, SVX_RES(FT_CAPSTYLE))),
    mpLBCapStyle(new ListBox(this, SVX_RES(LB_CAPSTYLE))),
    maStyleControl(SID_ATTR_LINE_STYLE, *pBindings, *this),
    maDashControl (SID_ATTR_LINE_DASH, *pBindings, *this),
    maWidthControl(SID_ATTR_LINE_WIDTH, *pBindings, *this),
    maColorControl(SID_ATTR_LINE_COLOR, *pBindings, *this),
    maStartControl(SID_ATTR_LINE_START, *pBindings, *this),
    maEndControl(SID_ATTR_LINE_END, *pBindings, *this),
    maLineEndListControl(SID_LINEEND_LIST, *pBindings, *this),
    maLineStyleListControl(SID_DASH_LIST, *pBindings, *this),
    maTransControl(SID_ATTR_LINE_TRANSPARENCE, *pBindings, *this),
    maEdgeStyle(SID_ATTR_LINE_JOINT, *pBindings, *this),
    maCapStyle(SID_ATTR_LINE_CAP, *pBindings, *this),
    maColor(COL_BLACK),
    mpColorUpdater(new ::svx::ToolboxButtonColorUpdater(SID_ATTR_LINE_COLOR, TBI_COLOR, mpTBColor.get(), TBX_UPDATER_MODE_CHAR_COLOR_NEW)),
    mpStyleItem(),
    mpDashItem(),
    mnTrans(0),
    meMapUnit(SFX_MAPUNIT_MM),
    mnWidthCoreValue(0),
    maLineEndList(),
    maLineStyleList(),
    mpStartItem(0),
    mpEndItem(0),
    maColorPopup(this, ::boost::bind(&LinePropertyPanel::CreateColorPopupControl, this, _1)),
    maLineWidthPopup(this, ::boost::bind(&LinePropertyPanel::CreateLineWidthPopupControl, this, _1)),
    maIMGColor(SVX_RES(IMG_COLOR)),
    maIMGNone(SVX_RES(IMG_NONE_ICON)),
    mpIMGWidthIcon(),
    mpIMGWidthIconH(),
    mxFrame(rxFrame),
    mpBindings(pBindings),
    mbColorAvailable(true),
    mbWidthValuable(true),
    maLayouter(*this)
{
    Initialize();
    FreeResource();

    // Setup the grid layouter.
    const sal_Int32 nMappedToolBoxWidth (Layouter::MapWidth(*this, TOOLBOX_WIDTH));

    maLayouter.GetCell(0,0).SetControl(*mpFTWidth);
    maLayouter.GetCell(1,0).SetControl(*mpTBWidthBackground).SetFixedWidth();

    maLayouter.GetCell(0,2).SetControl(*mpFTColor);
    maLayouter.GetCell(1,2).SetControl(*mpTBColorBackground).SetFixedWidth();

    maLayouter.GetCell(2,0).SetControl(*mpFTStyle);
    maLayouter.GetCell(3,0).SetControl(*mpLBStyle);

    maLayouter.GetCell(2,2).SetControl(*mpFTTrancparency);
    maLayouter.GetCell(3,2).SetControl(*mpMFTransparent);

    maLayouter.GetCell(4,0).SetControl(*mpFTArrow).SetGridWidth(3);
    maLayouter.GetCell(5,0).SetControl(*mpLBStart);
    maLayouter.GetCell(5,2).SetControl(*mpLBEnd);

    maLayouter.GetCell(6,0).SetControl(*mpFTEdgeStyle);
    maLayouter.GetCell(7,0).SetControl(*mpLBEdgeStyle);

    maLayouter.GetCell(6,2).SetControl(*mpFTCapStyle);
    maLayouter.GetCell(7,2).SetControl(*mpLBCapStyle);

    maLayouter.GetColumn(0)
        .SetWeight(1)
        .SetLeftPadding(Layouter::MapWidth(*this,SECTIONPAGE_MARGIN_HORIZONTAL))
        .SetMinimumWidth(nMappedToolBoxWidth);
    maLayouter.GetColumn(1)
        .SetWeight(0)
        .SetMinimumWidth(Layouter::MapWidth(*this, CONTROL_SPACING_HORIZONTAL));
    maLayouter.GetColumn(2)
        .SetWeight(1)
        .SetRightPadding(Layouter::MapWidth(*this,SECTIONPAGE_MARGIN_HORIZONTAL))
        .SetMinimumWidth(nMappedToolBoxWidth);

    // Make controls that display text handle short widths more
    // graceful.
    Layouter::PrepareForLayouting(*mpFTWidth);
    Layouter::PrepareForLayouting(*mpFTColor);
    Layouter::PrepareForLayouting(*mpFTStyle);
    Layouter::PrepareForLayouting(*mpFTTrancparency);
    Layouter::PrepareForLayouting(*mpFTArrow);
    Layouter::PrepareForLayouting(*mpFTEdgeStyle);
    Layouter::PrepareForLayouting(*mpFTCapStyle);
}



LinePropertyPanel::~LinePropertyPanel()
{
    // Destroy the toolboxes, then their background windows.
    mpTBWidth.reset();
    mpTBColor.reset();

    mpTBWidthBackground.reset();
    mpTBColorBackground.reset();
}



void LinePropertyPanel::Initialize()
{
    mpFTWidth->SetBackground(Wallpaper());
    mpFTColor->SetBackground(Wallpaper());
    mpFTStyle->SetBackground(Wallpaper());
    mpFTTrancparency->SetBackground(Wallpaper());
    mpFTArrow->SetBackground(Wallpaper());
    mpFTEdgeStyle->SetBackground(Wallpaper());
    mpFTCapStyle->SetBackground(Wallpaper());

    mpIMGWidthIcon.reset(new Image[8]);
    mpIMGWidthIcon[0] = Image(SVX_RES(IMG_WIDTH1_ICON));
    mpIMGWidthIcon[1] = Image(SVX_RES(IMG_WIDTH2_ICON));
    mpIMGWidthIcon[2] = Image(SVX_RES(IMG_WIDTH3_ICON));
    mpIMGWidthIcon[3] = Image(SVX_RES(IMG_WIDTH4_ICON));
    mpIMGWidthIcon[4] = Image(SVX_RES(IMG_WIDTH5_ICON));
    mpIMGWidthIcon[5] = Image(SVX_RES(IMG_WIDTH6_ICON));
    mpIMGWidthIcon[6] = Image(SVX_RES(IMG_WIDTH7_ICON));
    mpIMGWidthIcon[7] = Image(SVX_RES(IMG_WIDTH8_ICON));

    //high contrast
    mpIMGWidthIconH.reset(new Image[8]);
    mpIMGWidthIconH[0] = Image(SVX_RES(IMG_WIDTH1_ICON_H));
    mpIMGWidthIconH[1] = Image(SVX_RES(IMG_WIDTH2_ICON_H));
    mpIMGWidthIconH[2] = Image(SVX_RES(IMG_WIDTH3_ICON_H));
    mpIMGWidthIconH[3] = Image(SVX_RES(IMG_WIDTH4_ICON_H));
    mpIMGWidthIconH[4] = Image(SVX_RES(IMG_WIDTH5_ICON_H));
    mpIMGWidthIconH[5] = Image(SVX_RES(IMG_WIDTH6_ICON_H));
    mpIMGWidthIconH[6] = Image(SVX_RES(IMG_WIDTH7_ICON_H));
    mpIMGWidthIconH[7] = Image(SVX_RES(IMG_WIDTH8_ICON_H));

    meMapUnit = maWidthControl.GetCoreMetric();

    mpTBColor->SetItemImage(TBI_COLOR, maIMGColor);
    Size aTbxSize( mpTBColor->CalcWindowSizePixel() );
    mpTBColor->SetOutputSizePixel( aTbxSize );
    mpTBColor->SetItemBits( TBI_COLOR, mpTBColor->GetItemBits( TBI_COLOR ) | TIB_DROPDOWNONLY );
    mpTBColor->SetQuickHelpText(TBI_COLOR,String(SVX_RES(STR_QH_TB_COLOR))); //Add
    mpTBColor->SetBackground(Wallpaper());
    mpTBColor->SetPaintTransparent(true);
    Link aLink = LINK(this, LinePropertyPanel, ToolboxColorSelectHdl);
    mpTBColor->SetDropdownClickHdl ( aLink );
    mpTBColor->SetSelectHdl ( aLink );

    FillLineStyleList();
    SelectLineStyle();
    aLink = LINK( this, LinePropertyPanel, ChangeLineStyleHdl );
    mpLBStyle->SetSelectHdl( aLink );
    mpLBStyle->SetAccessibleName(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Style")));
    mpLBStyle->AdaptDropDownLineCountToMaximum();

    mpTBWidth->SetItemImage(TBI_WIDTH, mpIMGWidthIcon[0]);
    aTbxSize = mpTBWidth->CalcWindowSizePixel() ;
    mpTBWidth->SetOutputSizePixel( aTbxSize );
    mpTBWidth->SetItemBits( TBI_WIDTH, mpTBWidth->GetItemBits( TBI_WIDTH ) | TIB_DROPDOWNONLY );
    mpTBWidth->SetQuickHelpText(TBI_WIDTH,String(SVX_RES(STR_QH_TB_WIDTH))); //Add
    mpTBWidth->SetBackground(Wallpaper());
    mpTBWidth->SetPaintTransparent(true);
    aLink = LINK(this, LinePropertyPanel, ToolboxWidthSelectHdl);
    mpTBWidth->SetDropdownClickHdl ( aLink );
    mpTBWidth->SetSelectHdl ( aLink );

    FillLineEndList();
    SelectEndStyle(true);
    SelectEndStyle(false);
    aLink = LINK( this, LinePropertyPanel, ChangeStartHdl );
    mpLBStart->SetSelectHdl( aLink );
    mpLBStart->SetAccessibleName(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Beginning Style")));	//wj acc
    mpLBStart->AdaptDropDownLineCountToMaximum();
    aLink = LINK( this, LinePropertyPanel, ChangeEndHdl );
    mpLBEnd->SetSelectHdl( aLink );
    mpLBEnd->SetAccessibleName(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Ending Style")));	//wj acc
    mpLBEnd->AdaptDropDownLineCountToMaximum();

    aLink = LINK(this, LinePropertyPanel, ChangeTransparentHdl);
    mpMFTransparent->SetModifyHdl(aLink);
    mpMFTransparent->SetAccessibleName(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Transparency")));	//wj acc

    mpTBWidth->SetAccessibleRelationLabeledBy(mpFTWidth.get());
    mpTBColor->SetAccessibleRelationLabeledBy(mpFTColor.get());
    mpLBStyle->SetAccessibleRelationLabeledBy(mpFTStyle.get());
    mpMFTransparent->SetAccessibleRelationLabeledBy(mpFTTrancparency.get());
    mpLBStart->SetAccessibleRelationLabeledBy(mpFTArrow.get());
    mpLBEnd->SetAccessibleRelationLabeledBy(mpLBEnd.get());

    aLink = LINK( this, LinePropertyPanel, ChangeEdgeStyleHdl );
    mpLBEdgeStyle->SetSelectHdl( aLink );
    mpLBEdgeStyle->SetAccessibleName(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Corner Style")));

    aLink = LINK( this, LinePropertyPanel, ChangeCapStyleHdl );
    mpLBCapStyle->SetSelectHdl( aLink );
    mpLBCapStyle->SetAccessibleName(::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Cap Style")));
}



void LinePropertyPanel::SetupIcons(void)
{
    if(Theme::GetBoolean(Theme::Bool_UseSymphonyIcons))
    {
        // todo
    }
    else
    {
        // todo
    }
}



LinePropertyPanel* LinePropertyPanel::Create (
    Window* pParent,
    const cssu::Reference<css::frame::XFrame>& rxFrame,
    SfxBindings* pBindings)
{
    if (pParent == NULL)
        throw lang::IllegalArgumentException(A2S("no parent Window given to LinePropertyPanel::Create"), NULL, 0);
    if ( ! rxFrame.is())
        throw lang::IllegalArgumentException(A2S("no XFrame given to LinePropertyPanel::Create"), NULL, 1);
    if (pBindings == NULL)
        throw lang::IllegalArgumentException(A2S("no SfxBindings given to LinePropertyPanel::Create"), NULL, 2);

    return new LinePropertyPanel(
        pParent,
        rxFrame,
        pBindings);
}




void LinePropertyPanel::DataChanged(
    const DataChangedEvent& rEvent)
{
    (void)rEvent;

    SetupIcons();
}




void LinePropertyPanel::NotifyItemUpdate(
    sal_uInt16 nSID,
    SfxItemState eState,
    const SfxPoolItem* pState,
    const bool bIsEnabled)
{
    (void)bIsEnabled;
    const bool bDisabled(SFX_ITEM_DISABLED == eState);

    switch(nSID)
    {
        case SID_ATTR_LINE_COLOR:
        {
            if(bDisabled)
            {
                mpFTColor->Disable();
                mpTBColor->Disable();
            }
            else
            {
                mpFTColor->Enable();
                mpTBColor->Enable();
            }

            if(eState >= SFX_ITEM_DEFAULT)
            {
                const XLineColorItem* pItem = dynamic_cast< const XLineColorItem* >(pState);
                if(pItem)
                {
                    maColor = pItem->GetColorValue();
                    mbColorAvailable = true;
                    mpColorUpdater->Update(maColor);
                    break;
                }
            }

            mbColorAvailable = false;
            mpColorUpdater->Update(COL_WHITE);
            break;
        }
        case SID_ATTR_LINE_DASH:
        case SID_ATTR_LINE_STYLE:
        {
            if(bDisabled)
            {
                mpFTStyle->Disable();
                mpLBStyle->Disable();
            }
            else
            {
                mpFTStyle->Enable();
                mpLBStyle->Enable();
            }

            if(eState  >= SFX_ITEM_DEFAULT)
            {
                if(nSID == SID_ATTR_LINE_STYLE)
                {
                    const XLineStyleItem* pItem = dynamic_cast< const XLineStyleItem* >(pState);

                    if(pItem)
                    {
                        mpStyleItem.reset(pState ? (XLineStyleItem*)pItem->Clone() : 0);
                    }
                }
                else // if(nSID == SID_ATTR_LINE_DASH)
                {
                    const XLineDashItem* pItem = dynamic_cast< const XLineDashItem* >(pState);

                    if(pItem)
                    {
                        mpDashItem.reset(pState ? (XLineDashItem*)pItem->Clone() : 0);
                    }
                }
            }
            else
            {
                if(nSID == SID_ATTR_LINE_STYLE)
                {
                    mpStyleItem.reset(0);
                }
                else
                {
                    mpDashItem.reset(0);
                }
            }

            SelectLineStyle();
            break;
        }
        case SID_ATTR_LINE_TRANSPARENCE:
        {
            if(bDisabled)
            {
                mpFTTrancparency->Disable();
                mpMFTransparent->Disable();
            }
            else
            {
                mpFTTrancparency->Enable();
                mpMFTransparent->Enable();
            }

            if(eState >= SFX_ITEM_DEFAULT)
            {
                const XLineTransparenceItem* pItem = dynamic_cast< const XLineTransparenceItem* >(pState);

                if(pItem)
                {
                    mnTrans = pItem->GetValue();
                    mpMFTransparent->SetValue(mnTrans);
                    break;
                }
            }

            mpMFTransparent->SetValue(0);//add
            mpMFTransparent->SetText(String());
            break;
        }
        case SID_ATTR_LINE_WIDTH:
        {
            if(bDisabled)
            {
                mpTBWidth->Disable();
                mpFTWidth->Disable();
            }
            else
            {
                mpTBWidth->Enable();
                mpFTWidth->Enable();
            }

            if(eState >= SFX_ITEM_DEFAULT)
            {
                const XLineWidthItem* pItem = dynamic_cast< const XLineWidthItem* >(pState);

                if(pItem)
                {
                    mnWidthCoreValue = pItem->GetValue();
                    mbWidthValuable = true;
                    SetWidthIcon();
                    break;
                }
            }

            mbWidthValuable = false;
            SetWidthIcon();
            break;
        }
        case SID_ATTR_LINE_START:
        {
            if(bDisabled)
            {
                mpFTArrow->Disable();
                mpLBStart->Disable();
            }
            else
            {
                mpFTArrow->Enable();
                mpLBStart->Enable();
            }

            if(eState >= SFX_ITEM_DEFAULT)
            {
                const XLineStartItem* pItem = dynamic_cast< const XLineStartItem* >(pState);

                if(pItem)
                {
                    mpStartItem.reset(pItem ? (XLineStartItem*)pItem->Clone() : 0);
                    SelectEndStyle(true);
                    break;
                }
            }

            mpStartItem.reset(0);
            SelectEndStyle(true);
            break;
        }
        case SID_ATTR_LINE_END:
        {
            if(bDisabled)
            {
                mpFTArrow->Disable();
                mpLBEnd->Disable();
            }
            else
            {
                mpFTArrow->Enable();
                mpLBEnd->Enable();
            }

            if(eState >= SFX_ITEM_DEFAULT)
            {
                const XLineEndItem* pItem = dynamic_cast< const XLineEndItem* >(pState);

                if(pItem)
                {
                    mpEndItem.reset(pItem ? (XLineEndItem*)pItem->Clone() : 0);
                    SelectEndStyle(false);
                    break;
                }
            }

            mpEndItem.reset(0);
            SelectEndStyle(false);
            break;
        }
        case SID_LINEEND_LIST:
        {
            FillLineEndList();
            SelectEndStyle(true);
            SelectEndStyle(false);
            break;
        }
        case SID_DASH_LIST:
        {
            FillLineStyleList();
            SelectLineStyle();
            break;
        }
        case SID_ATTR_LINE_JOINT:
        {
            if(bDisabled)
            {
                mpLBEdgeStyle->Disable();
                mpFTEdgeStyle->Disable();
            }
            else
            {
                mpLBEdgeStyle->Enable();
                mpFTEdgeStyle->Enable();
            }

            if(eState >= SFX_ITEM_DEFAULT)
            {
                const XLineJointItem* pItem = dynamic_cast< const XLineJointItem* >(pState);

                if(pItem)
                {
                    sal_uInt16 nEntryPos(0);

                    switch(pItem->GetValue())
                    {
                        case com::sun::star::drawing::LineJoint_MIDDLE:
                        case com::sun::star::drawing::LineJoint_ROUND:
                        {
                            nEntryPos = 1;
                            break;
                        }
                        case com::sun::star::drawing::LineJoint_NONE:
                        {
                            nEntryPos = 2;
                            break;
                        }
                        case com::sun::star::drawing::LineJoint_MITER:
                        {
                            nEntryPos = 3;
                            break;
                        }
                        case com::sun::star::drawing::LineJoint_BEVEL:
                        {
                            nEntryPos = 4;
                            break;
                        }

                        default:
                            break;
                    }

                    if(nEntryPos)
                    {
                        mpLBEdgeStyle->SelectEntryPos(nEntryPos - 1);
                        break;
                    }
                }
            }

            mpLBEdgeStyle->SetNoSelection();
            break;
        }
        case SID_ATTR_LINE_CAP:
        {
            if(bDisabled)
            {
                mpLBCapStyle->Disable();
                mpFTCapStyle->Disable();
            }
            else
            {
                mpLBCapStyle->Enable();
                mpLBCapStyle->Enable();
            }

            if(eState >= SFX_ITEM_DEFAULT)
            {
                const XLineCapItem* pItem = dynamic_cast< const XLineCapItem* >(pState);

                if(pItem)
                {
                    sal_uInt16 nEntryPos(0);

                    switch(pItem->GetValue())
                    {
                        case com::sun::star::drawing::LineCap_BUTT:
                        {
                            nEntryPos = 1;
                            break;
                        }
                        case com::sun::star::drawing::LineCap_ROUND:
                        {
                            nEntryPos = 2;
                            break;
                        }
                        case com::sun::star::drawing::LineCap_SQUARE:
                        {
                            nEntryPos = 3;
                            break;
                        }

                        default:
                            break;
                    }

                    if(nEntryPos)
                    {
                        mpLBCapStyle->SelectEntryPos(nEntryPos - 1);
                        break;
                    }
                }
            }

            mpLBCapStyle->SetNoSelection();
            break;
        }
    }
}




SfxBindings* LinePropertyPanel::GetBindings()
{
    return mpBindings;
}



IMPL_LINK( LinePropertyPanel, ImplPopupModeEndHdl, FloatingWindow*, EMPTYARG )
{
    return 0;
}




IMPL_LINK(LinePropertyPanel, ToolboxColorSelectHdl,ToolBox*, pToolBox)
{
    sal_uInt16 nId = pToolBox->GetCurItemId();
    if(nId == TBI_COLOR)
    {
        maColorPopup.Show(*pToolBox);
        maColorPopup.SetCurrentColor(maColor, mbColorAvailable);
    }
    return 0;
}




IMPL_LINK(LinePropertyPanel, ChangeLineStyleHdl, ToolBox*, /* pToolBox */)
{
    const sal_uInt16 nPos(mpLBStyle->GetSelectEntryPos());

    if(LISTBOX_ENTRY_NOTFOUND != nPos && nPos != mpLBStyle->GetSavedValue())
    {
        if(0 == nPos)
        {
            // XLINE_NONE
            const XLineStyleItem aItem(XLINE_NONE);

            GetBindings()->GetDispatcher()->Execute(SID_ATTR_LINE_STYLE, SFX_CALLMODE_RECORD, &aItem, 0L);
        }
        else if(1 == nPos)
        {
            // XLINE_SOLID
            const XLineStyleItem aItem(XLINE_SOLID);

            GetBindings()->GetDispatcher()->Execute(SID_ATTR_LINE_STYLE, SFX_CALLMODE_RECORD, &aItem, 0L);
        }
        else if(maLineStyleList.get() && maLineStyleList->Count() > (long)(nPos - 2))
        {
            // XLINE_DASH
            const XLineStyleItem aItemA(XLINE_DASH);
            const XDashEntry* pDashEntry = maLineStyleList->GetDash(nPos - 2);
            OSL_ENSURE(pDashEntry, "OOps, got empty XDash from XDashList (!)");
            const XLineDashItem aItemB(
                pDashEntry ? pDashEntry->GetName() : String(),
                pDashEntry ? pDashEntry->GetDash() : XDash());

            GetBindings()->GetDispatcher()->Execute(SID_ATTR_LINE_STYLE, SFX_CALLMODE_RECORD, &aItemA, 0L);
            GetBindings()->GetDispatcher()->Execute(SID_ATTR_LINE_DASH, SFX_CALLMODE_RECORD, &aItemB, 0L);
        }
    }

    return 0;
}



IMPL_LINK(LinePropertyPanel, ChangeStartHdl, void*, EMPTYARG)
{
    sal_uInt16	nPos = mpLBStart->GetSelectEntryPos();
    if( nPos != LISTBOX_ENTRY_NOTFOUND && nPos != mpLBStart->GetSavedValue() )
    {
        XLineStartItem* pItem = NULL;
        if( nPos == 0 )
            pItem = new XLineStartItem();
        else if( maLineEndList.get() && maLineEndList->Count() > (long) ( nPos - 1 ) )
            pItem = new XLineStartItem( mpLBStart->GetSelectEntry(),maLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() );
        GetBindings()->GetDispatcher()->Execute(SID_ATTR_LINEEND_STYLE, SFX_CALLMODE_RECORD, pItem,  0L);
        delete pItem;
    }
    return 0;
}




IMPL_LINK(LinePropertyPanel, ChangeEndHdl, void*, EMPTYARG)
{
    sal_uInt16	nPos = mpLBEnd->GetSelectEntryPos();
    if( nPos != LISTBOX_ENTRY_NOTFOUND && nPos != mpLBEnd->GetSavedValue() )
    {
        XLineEndItem* pItem = NULL;
        if( nPos == 0 )
            pItem = new XLineEndItem();
        else if( maLineEndList.get() && maLineEndList->Count() > (long) ( nPos - 1 ) )
            pItem = new XLineEndItem( mpLBEnd->GetSelectEntry(), maLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() );
        GetBindings()->GetDispatcher()->Execute(SID_ATTR_LINEEND_STYLE, SFX_CALLMODE_RECORD, pItem,  0L);
        delete pItem;
    }
    return 0;
}




IMPL_LINK(LinePropertyPanel, ChangeEdgeStyleHdl, void*, EMPTYARG)
{
    const sal_uInt16 nPos(mpLBEdgeStyle->GetSelectEntryPos());

    if(LISTBOX_ENTRY_NOTFOUND != nPos && nPos != mpLBEdgeStyle->GetSavedValue())
    {
        XLineJointItem* pItem = 0;

        switch(nPos)
        {
            case 0: // rounded
            {
                pItem = new XLineJointItem(com::sun::star::drawing::LineJoint_ROUND);
                break;
            }
            case 1: // none
            {
                pItem = new XLineJointItem(com::sun::star::drawing::LineJoint_NONE);
                break;
            }
            case 2: // mitered
            {
                pItem = new XLineJointItem(com::sun::star::drawing::LineJoint_MITER);
                break;
            }
            case 3: // beveled
            {
                pItem = new XLineJointItem(com::sun::star::drawing::LineJoint_BEVEL);
                break;
            }
        }

        GetBindings()->GetDispatcher()->Execute(SID_ATTR_LINE_JOINT, SFX_CALLMODE_RECORD, pItem,  0L);
        delete pItem;
    }
    return 0;
}




IMPL_LINK(LinePropertyPanel, ChangeCapStyleHdl, void*, EMPTYARG)
{
    const sal_uInt16 nPos(mpLBCapStyle->GetSelectEntryPos());

    if(LISTBOX_ENTRY_NOTFOUND != nPos && nPos != mpLBCapStyle->GetSavedValue())
    {
        XLineCapItem* pItem = 0;

        switch(nPos)
        {
            case 0: // flat
            {
                pItem = new XLineCapItem(com::sun::star::drawing::LineCap_BUTT);
                break;
            }
            case 1: // round
            {
                pItem = new XLineCapItem(com::sun::star::drawing::LineCap_ROUND);
                break;
            }
            case 2: // square
            {
                pItem = new XLineCapItem(com::sun::star::drawing::LineCap_SQUARE);
                break;
            }
        }

        GetBindings()->GetDispatcher()->Execute(SID_ATTR_LINE_CAP, SFX_CALLMODE_RECORD, pItem,  0L);
        delete pItem;
    }
    return 0;
}




IMPL_LINK(LinePropertyPanel, ToolboxWidthSelectHdl,ToolBox*, pToolBox)
{
    if (pToolBox->GetCurItemId() == TBI_WIDTH)
    {
        maLineWidthPopup.SetWidthSelect(mnWidthCoreValue, mbWidthValuable, meMapUnit);
        maLineWidthPopup.Show(*pToolBox);
    }
    return 0;
}




IMPL_LINK( LinePropertyPanel, ChangeTransparentHdl, void *, EMPTYARG )
{
    sal_uInt16 nVal = (sal_uInt16)mpMFTransparent->GetValue();
    XLineTransparenceItem aItem( nVal );

    GetBindings()->GetDispatcher()->Execute(SID_ATTR_LINE_STYLE, SFX_CALLMODE_RECORD, &aItem, 0L);
    return( 0L );
}




namespace
{
    Color GetTransparentColor (void)
    {
        return COL_TRANSPARENT;
    }
} // end of anonymous namespace

PopupControl* LinePropertyPanel::CreateColorPopupControl (PopupContainer* pParent)
{
    return new ColorControl(
        pParent,
        mpBindings,
        SVX_RES(RID_POPUPPANEL_LINEPAGE_COLOR),
        SVX_RES(VS_COLOR),
        ::boost::bind(GetTransparentColor),
        ::boost::bind(&LinePropertyPanel::SetColor, this, _1, _2),
        pParent,
        0);
}




PopupControl* LinePropertyPanel::CreateLineWidthPopupControl (PopupContainer* pParent)
{
    return new LineWidthControl(pParent, *this);
}




void LinePropertyPanel::EndLineWidthPopupMode (void)
{
    maLineWidthPopup.Hide();
}




void LinePropertyPanel::Resize (void)
{
    maLayouter.Layout();
}




void LinePropertyPanel::SetWidthIcon(int n)
{
    if(n==0)
        mpTBWidth->SetItemImage( TBI_WIDTH, maIMGNone);
    else
        mpTBWidth->SetItemImage( TBI_WIDTH, GetDisplayBackground().GetColor().IsDark() ? mpIMGWidthIconH[n-1] : mpIMGWidthIcon[n-1]);
}



void LinePropertyPanel::SetWidthIcon()
{
    if(!mbWidthValuable)
    {
        mpTBWidth->SetItemImage( TBI_WIDTH, maIMGNone);
        return;
    }

    long nVal = LogicToLogic(mnWidthCoreValue * 10,(MapUnit)meMapUnit , MAP_POINT);

    if(nVal <= 6)
        mpTBWidth->SetItemImage( TBI_WIDTH, GetDisplayBackground().GetColor().IsDark() ? mpIMGWidthIconH[0] : mpIMGWidthIcon[0]);
    else if(nVal > 6 && nVal <= 9)
        mpTBWidth->SetItemImage( TBI_WIDTH, GetDisplayBackground().GetColor().IsDark() ? mpIMGWidthIconH[1] : mpIMGWidthIcon[1]);
    else if(nVal > 9 && nVal <= 12)
        mpTBWidth->SetItemImage( TBI_WIDTH, GetDisplayBackground().GetColor().IsDark() ? mpIMGWidthIconH[2] : mpIMGWidthIcon[2]);
    else if(nVal > 12 && nVal <= 19)
        mpTBWidth->SetItemImage( TBI_WIDTH, GetDisplayBackground().GetColor().IsDark() ? mpIMGWidthIconH[3] : mpIMGWidthIcon[3]);
    else if(nVal > 19 && nVal <= 26)
        mpTBWidth->SetItemImage( TBI_WIDTH, GetDisplayBackground().GetColor().IsDark() ? mpIMGWidthIconH[4] : mpIMGWidthIcon[4]);
    else if(nVal > 26 && nVal <= 37)
        mpTBWidth->SetItemImage( TBI_WIDTH, GetDisplayBackground().GetColor().IsDark() ? mpIMGWidthIconH[5] : mpIMGWidthIcon[5]);
    else if(nVal > 37 && nVal <=52)
        mpTBWidth->SetItemImage( TBI_WIDTH, GetDisplayBackground().GetColor().IsDark() ? mpIMGWidthIconH[6] : mpIMGWidthIcon[6]);
    else if(nVal > 52)
        mpTBWidth->SetItemImage( TBI_WIDTH, GetDisplayBackground().GetColor().IsDark() ? mpIMGWidthIconH[7] : mpIMGWidthIcon[7]);

}



void LinePropertyPanel::SetColor (
    const String& rsColorName,
    const Color aColor)
{
    XLineColorItem aColorItem(rsColorName, aColor);
    mpBindings->GetDispatcher()->Execute(SID_ATTR_LINE_COLOR, SFX_CALLMODE_RECORD, &aColorItem, 0L);
    maColor = aColor;
}



void LinePropertyPanel::SetWidth(long nWidth)
{
    mnWidthCoreValue = nWidth;
    mbWidthValuable = true;
}



void  LinePropertyPanel::FillLineEndList()
{
    SfxObjectShell* pSh = SfxObjectShell::Current();
    if ( pSh && pSh->GetItem( SID_LINEEND_LIST ) )
    {
        mpLBStart->Enable();
        SvxLineEndListItem aItem( *(const SvxLineEndListItem*)(pSh->GetItem( SID_LINEEND_LIST ) ) );
        maLineEndList = aItem.GetLineEndList();

        if(maLineEndList.get())
        {
            FillLineEndListBox(*mpLBStart, *mpLBEnd, maLineEndList);
        }

        mpLBStart->SelectEntryPos(0);
        mpLBEnd->SelectEntryPos(0);
    }
    else
    {
        mpLBStart->Disable();
        mpLBEnd->Disable();
    }
}



void  LinePropertyPanel::FillLineStyleList()
{
    SfxObjectShell* pSh = SfxObjectShell::Current();
    if ( pSh && pSh->GetItem( SID_DASH_LIST ) )
    {
        mpLBStyle->Enable();
        SvxDashListItem aItem( *(const SvxDashListItem*)(pSh->GetItem( SID_DASH_LIST ) ) );
        maLineStyleList = aItem.GetDashList();

        if(maLineStyleList.get())
        {
            FillLineStyleListBox(*mpLBStyle, maLineStyleList);
        }

        mpLBStyle->SelectEntryPos(0);
    }
    else
    {
        mpLBStyle->Disable();
    }
}



void LinePropertyPanel::SelectLineStyle()
{
    if( !mpStyleItem.get() || !mpDashItem.get() )
    {
        mpLBStyle->SetNoSelection();
        mpLBStyle->Disable();
        return;
    }

    const XLineStyle eXLS(mpStyleItem ? (XLineStyle)mpStyleItem->GetValue() : XLINE_NONE);
    bool bSelected(false);

    switch(eXLS)
    {
        case XLINE_NONE:
            break;
        case XLINE_SOLID:
            mpLBStyle->SelectEntryPos(1);
            bSelected = true;
            break;
        default:
            if(mpDashItem && maLineStyleList.get())
            {
                const XDash& rDash = mpDashItem->GetDashValue();
                for(sal_Int32 a(0);!bSelected &&  a < maLineStyleList->Count(); a++)
                {
                    XDashEntry* pEntry = maLineStyleList->GetDash(a);
                    const XDash& rEntry = pEntry->GetDash();
                    if(rDash == rEntry)
                    {
                        mpLBStyle->SelectEntryPos((sal_uInt16)a + 2);
                        bSelected = true;
                    }
                }
            }
            break;
    }

    if(!bSelected)
        mpLBStyle->SelectEntryPos( 0 );
}

void LinePropertyPanel::SelectEndStyle(bool bStart)
{
    sal_Bool bSelected(false);

    if(bStart)
    {
        if( !mpStartItem.get() )
        {
            mpLBStart->SetNoSelection();
            mpLBStart->Disable();
            return;
        }

        if(mpStartItem && maLineEndList.get())
        {
            const basegfx::B2DPolyPolygon& rItemPolygon = mpStartItem->GetLineStartValue();
            for(sal_Int32 a(0);!bSelected &&  a < maLineEndList->Count(); a++)
            {
                XLineEndEntry* pEntry = maLineEndList->GetLineEnd(a);
                const basegfx::B2DPolyPolygon& rEntryPolygon = pEntry->GetLineEnd();
                if(rItemPolygon == rEntryPolygon)
                {
                    mpLBStart->SelectEntryPos((sal_uInt16)a + 1);
                    bSelected = true;
                }
            }
        }

        if(!bSelected)
        {
            mpLBStart->SelectEntryPos( 0 );
        }
    }
    else
    {
        if( !mpEndItem.get() )
        {
            mpLBEnd->SetNoSelection();
            mpLBEnd->Disable();
            return;
        }

        if(mpEndItem && maLineEndList.get())
        {
            const basegfx::B2DPolyPolygon& rItemPolygon = mpEndItem->GetLineEndValue();
            for(sal_Int32 a(0);!bSelected &&  a < maLineEndList->Count(); a++)
            {
                XLineEndEntry* pEntry = maLineEndList->GetLineEnd(a);
                const basegfx::B2DPolyPolygon& rEntryPolygon = pEntry->GetLineEnd();
                if(rItemPolygon == rEntryPolygon)
                {
                    mpLBEnd->SelectEntryPos((sal_uInt16)a + 1);
                    bSelected = true;
                }
            }
        }

        if(!bSelected)
        {
            mpLBEnd->SelectEntryPos( 0 );
        }
    }
}


} } // end of namespace svx::sidebar

// eof
