/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
 * This file is part of the Collabora Office project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <svx/ThemeColorsToolBoxControl.hxx>
#include <svx/ColorSets.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <sfx2/viewsh.hxx>
#include <sfx2/objsh.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <vcl/svapp.hxx>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <comphelper/processfactory.hxx>
#include <comphelper/dispatchcommand.hxx>
#include <comphelper/propertyvalue.hxx>
#include <comphelper/unique_unlock.hxx>

ThemeColorsToolBoxControl::ThemeColorsToolBoxControl() {}

ThemeColorsToolBoxControl::~ThemeColorsToolBoxControl() {}

void ThemeColorsToolBoxControl::disposing(std::unique_lock<std::mutex>& rGuard)
{
    {
        comphelper::unique_unlock aUnlock(rGuard);
        SolarMutexGuard aSolarMutexGuard;
        m_xVclBox.disposeAndClear();
    }
    svt::ToolboxController::disposing(rGuard);
}

void SAL_CALL
ThemeColorsToolBoxControl::statusChanged(const css::frame::FeatureStateEvent& /*rEvent*/)
{
}

css::uno::Reference<css::awt::XWindow>
ThemeColorsToolBoxControl::createItemWindow(const css::uno::Reference<css::awt::XWindow>& rParent)
{
    css::uno::Reference<css::awt::XWindow> xItemWindow;

    VclPtr<vcl::Window> pParent = VCLUnoHelper::GetWindow(rParent);
    if (pParent)
    {
        SolarMutexGuard aSolarMutexGuard;

        m_xVclBox = VclPtr<ThemeColorsPaneWrapper>::Create(pParent, m_xFrame);
        xItemWindow = VCLUnoHelper::GetInterface(m_xVclBox.get());
    }
    return xItemWindow;
}

void SAL_CALL ThemeColorsToolBoxControl::update() {}

OUString SAL_CALL ThemeColorsToolBoxControl::getImplementationName()
{
    return u"com.sun.star.comp.svx.ThemeColorsToolBoxControl"_ustr;
}

bool SAL_CALL ThemeColorsToolBoxControl::supportsService(const OUString& rServiceName)
{
    return cppu::supportsService(this, rServiceName);
}

cpo::uno::Sequence<OUString> SAL_CALL ThemeColorsToolBoxControl::getSupportedServiceNames()
{
    return { u"com.sun.star.frame.ToolbarController"_ustr };
}

// Export function for service registration
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
com_sun_star_comp_svx_ThemeColorsToolBoxControl_get_implementation(
    css::uno::XComponentContext* /*rxContext*/, cpo::uno::Sequence<cpo::uno::Any> const&)
{
    return cppu::acquire(new ThemeColorsToolBoxControl());
}

ThemeColorsPaneWrapper::ThemeColorsPaneWrapper(
    vcl::Window* pParent, const css::uno::Reference<css::frame::XFrame>& rxFrame)
    : InterimItemWindow(pParent, u"svx/ui/themeselectorpanel.ui"_ustr, u"ThemeSelectorPanel"_ustr,
                        true, reinterpret_cast<sal_uInt64>(SfxViewShell::Current()))
    , svx::ThemeColorsPaneBase(m_xBuilder->weld_icon_view(u"iconview_theme_colors"_ustr))
    , m_xFrame(rxFrame)
{
    // Override selection handler to apply theme on single click
    if (mxIconViewThemeColors)
        mxIconViewThemeColors->connect_selection_changed(
            LINK(this, ThemeColorsPaneWrapper, SelectionChangedHdl));

    StartListening(svx::ColorSets::get());
    initColorSets();
    SetOptimalSize();
}

ThemeColorsPaneWrapper::~ThemeColorsPaneWrapper() { disposeOnce(); }

void ThemeColorsPaneWrapper::SetOptimalSize() { SetSizePixel(GetOptimalSize()); }

void ThemeColorsPaneWrapper::Notify(SfxBroadcaster&, const SfxHint&) { initColorSets(); }

void ThemeColorsPaneWrapper::dispose()
{
    EndListeningAll();
    mxIconViewThemeColors.reset();
    InterimItemWindow::dispose();
}

void ThemeColorsPaneWrapper::onColorSetActivated()
{
    if (!mpCurrentColorSet)
        return;

    cpo::uno::Sequence<css::beans::PropertyValue> aArgs{ comphelper::makePropertyValue(
        u"ThemeName"_ustr, mpCurrentColorSet->getName()) };

    comphelper::dispatchCommand(u".uno:ApplyTheme"_ustr, m_xFrame, aArgs);
}

IMPL_LINK_NOARG(ThemeColorsPaneWrapper, SelectionChangedHdl, weld::IconView&, void)
{
    // Call base class selection handler first to update mpCurrentColorSet
    svx::ThemeColorsPaneBase::SelectionChangedHdl(*mxIconViewThemeColors);

    // Apply theme on single-click
    onColorSetActivated();
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
