#include <sal/main.h>
#include <iostream>
#include <cppuhelper/bootstrap.hxx>
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/text/XTextDocument.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>

using namespace com::sun::star::container;
using namespace com::sun::star::style;
using namespace com::sun::star::text;
using namespace com::sun::star::awt;
using namespace com::sun::star::beans;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::frame;
using ::rtl::OUString;
using ::rtl::OUStringToOString;

SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
{
    try
    {
        //  получаем контекст компонентов офиса
        Reference< XComponentContext > xContext(::cppu::bootstrap());
        if (!xContext.is())
        {
            fprintf(stderr, "no component context!\n");
            return 1;
        }

        // получаем сервис-менеджер
        Reference< XMultiComponentFactory > xServiceManager(
            xContext->getServiceManager());
        if (!xServiceManager.is())
        {
            fprintf(stderr, "no service manager!\n");
            return 1;
        }

        // получаем экземпляр сервиса UNO Desktop
        // получаем интерфейс XComponentLoader
        Reference<XComponentLoader> xLoader(xContext->getServiceManager()->createInstanceWithContext(
            "com.sun.star.frame.Desktop", xContext), UNO_QUERY);


        // создаем новый документ или загружаем существующий
        Sequence<PropertyValue> props(2);
        PropertyValue prop[2];
        prop[0].Name = "FliterName";
        prop[0].Value <<= OUString("writer8");
        prop[1].Name = "Overwrite";
        prop[1].Value <<= Any(true);
        props[0] = prop[0];
        props[1] = prop[1];
        Reference<com::sun::star::uno::XInterface> xComponent = xLoader->loadComponentFromURL(
            "file:///C:/test/document.odt", "_blank", 0, props);



        // Получаем объект XTextDocument из объекта xComponent
        Reference<XTextDocument> xDoc(xComponent, UNO_QUERY_THROW);
        // Получаем объект XStyleFamiliesSupplier из объекта xTextDocument
        Reference<XStyleFamiliesSupplier> xStyleFamiliesSupplier(xDoc, UNO_QUERY_THROW);
        // Получаем объект XNameAccess, который содержит список семейств стилей
        Reference<XNameAccess> xStyleFamilies = xStyleFamiliesSupplier->getStyleFamilies();
        // Получаем список имен семейств стилей
        Sequence<OUString> styleFamilyNames = xStyleFamilies->getElementNames();
        // Выводим количество семейств стилей
        std::cout << "Number of Style Family Names: " << styleFamilyNames.getLength() << std::endl;
        // Итерируем по списку имен семейств стилей и выводим имена стилей каждого семейства
        for (sal_Int32 i = 0; i < styleFamilyNames.getLength(); i++)
        {
            OUString styleFamilyName = styleFamilyNames[i];
            std::cout << "Style Family: " << styleFamilyName << std::endl;

            // Получаем объект XNameAccess, который содержит список стилей текущего семейства
            Reference<XNameAccess> xStyles = Reference<XNameAccess>(xStyleFamilies->getByName(styleFamilyName), UNO_QUERY_THROW);
            // Получаем список имен стилей текущего семейства
            Sequence<OUString> styleNames = xStyles->getElementNames();
            // Итерируем по списку имен стилей текущего семейства и выводим их в консоль
            for (sal_Int32 j = 0; j < styleNames.getLength(); j++)
            {
                OUString styleName = styleNames[j];
                std::cout << "    Style: " << styleName << std::endl;
            }
        }

        // Получаем объект документа
        Reference<XTextDocument>  xTextDocument(xComponent, UNO_QUERY);
        //Получаем объект текста
        Reference<XText> xText = xTextDocument->getText();
        // Создаем курсор для работы с текстом
        Reference<XTextCursor> xCursor = xText->createTextCursor();
        // Выделяем весь текст в документе
        xCursor->gotoStart(true);
        xCursor->gotoEnd(true);
        //Получем объект XPropertySet для применения стиля текста
        Reference<XPropertySet> xCursorProps(xCursor, UNO_QUERY);
        //Применяем метод setPropertyValue() для установки стиля 
        xCursorProps->setPropertyValue("ParaStyleName", Any(OUString("Title")));



        // получаем интерфейс XStorable для текущего документа
        Reference< XStorable > xStorable(xComponent, UNO_QUERY);
        if (!xStorable.is())
        {
            fprintf(stderr, "getting XStorable interface failed!\n");
            return 1;
        }

        // задаем URL для сохранения документа
        OUString saveUrl("file:///C:/test/document.odt");

        // сохраняем документ
        xStorable->storeAsURL(saveUrl, props);

        // закрываем документ

       //xDoc->dispose();
    }
    catch (::cppu::BootstrapException& e)
    {
        fprintf(stderr, "caught BootstrapException: %s\n",
            OUStringToOString(e.getMessage(), RTL_TEXTENCODING_ASCII_US).getStr());
        return 1;
    }
    catch (Exception& e)
    {
        fprintf(stderr, "caught UNO exception: %s\n",
            OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US).getStr());
        return 1;
    }

    return 0;
}
