/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice 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/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   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 .
 */

#ifndef INCLUDED_WRITERFILTER_INC_DMAPPER_RESOURCEMODEL_HXX
#define INCLUDED_WRITERFILTER_INC_DMAPPER_RESOURCEMODEL_HXX

#include <string>
#include <memory>
#include <sal/types.h>
#include <com/sun/star/drawing/XShape.hpp>
#include <com/sun/star/uno/Any.hxx>
/**
   @file resourcemodel.hxx

   The classes in this file define the interfaces for the resource
   model of the DocTokenizer:

   @image html doctok.png

   A resource is a set of events that describe an object. A resource
   is only an abstract concept. It is not instantiated to a class.

   A reference to a resource represents the object that the resource
   describes. The reference can be resolved thereby generating the
   events of the resource.

   A handler receives the events generated by resolving a
   reference. There are several types of handlers each accepting their
   specific set of events.

   References always have a parameter determining the kind of handler
   they send the events they generate to. The set of events generated
   by resolving the reference is a subset of the events received by
   the handler.
*/


typedef sal_uInt32 Id;

namespace writerfilter {

/**
    Reference to an resource that generates events and sends them to a
    handler.

    The reference can be resolved, i.e. the resource generates its
    events. The events must be suitable for the handler type given by
    the template parameter.

    @attention The parameter of the template does not determine the
    type of the reference's target. It determines the type of the handler!

    Example:

    A Word document can be represented as a stream of events. Event
    types in a Word document are text, properties, tables, starts and
    ends of groups. These can be handled by a stream handler (@see
    Stream). Thus a reference to a Word document is resolved by
    sending these events to a stream handler.
*/

template <class T>
class SAL_DLLPUBLIC_TEMPLATE Reference
{
public:
    /**
        Pointer to reference

        @attention The ownership of a reference is transferred when
        the reference is passed.
    */
    typedef std::shared_ptr< Reference<T> > Pointer_t;

    /**
       Resolves the reference.

       The events of the references target resource are generated and
       send to a handler.

       @param rHandler         handler which receives the events
     */
    virtual void resolve(T & rHandler) = 0;

protected:
    ~Reference() {}
};

class Value;
class Sprm;

/**
   Handler for properties.
 */
class Properties
{
public:
    /**
       Receives an attribute.

       @param name     name of the attribute
       @param val      value of the attribute
     */
    virtual void attribute(Id name, Value & val) = 0;

    /**
       Receives a SPRM.

       @param  sprm      the SPRM received
    */
    virtual void sprm(Sprm & sprm) = 0;

protected:
    ~Properties() {}
};

/**
   Handler for tables.
 */
class Table
{
public:
    typedef std::shared_ptr<Table> Pointer_t;

    /**
       Receives an entry of the table.

       @param pos     position of the entry in the table
       @param ref     reference to properties of the entry
     */
    virtual void entry(int pos, writerfilter::Reference<Properties>::Pointer_t ref) = 0;

protected:
    ~Table() {}
};

/**
   Handler for binary objects.
 */
class BinaryObj
{
public:
    /**
       Receives binary data of the object.

       @param buf     pointer to buffer containing the data
       @param len     size of buffer
       @param ref     reference to properties of binary object
     */
    virtual void data(const sal_uInt8* buf, size_t len,
                      writerfilter::Reference<Properties>::Pointer_t ref) = 0;

protected:
    ~BinaryObj() {}
};

const sal_uInt8 cFieldStart = 0x13;
const sal_uInt8 cFieldSep = 0x14;
const sal_uInt8 cFieldEnd = 0x15;

/**
   Handler for a stream.
 */
class Stream
{
public:

    /**
       Pointer to this stream.
     */
    typedef std::shared_ptr<Stream> Pointer_t;

    /**
       Receives start mark for group with the same section properties.
     */
    virtual void startSectionGroup() = 0;

    /**
       Receives end mark for group with the same section properties.
    */
    virtual void endSectionGroup() = 0;

    /// The current section is the last one in this body text.
    virtual void markLastSectionGroup( ) { };

    /**
       Receives start mark for group with the same paragraph properties.
     */
    virtual void startParagraphGroup() = 0;

    /**
       Receives end mark for group with the same paragraph properties.
     */
    virtual void endParagraphGroup() = 0;

    virtual void markLastParagraphInSection( ) { };

    /**
       Receives start mark for group with the same character properties.
     */
    virtual void startCharacterGroup() = 0;

    /**
       Receives end mark for group with the same character properties.
     */
    virtual void endCharacterGroup() = 0;

    /**
      Receives a shape.
     */
    virtual void startShape(css::uno::Reference<css::drawing::XShape> const& xShape) = 0;

    virtual void endShape( ) = 0;

    /**
       Receives 8-bit per character text.

       @param data  buffer containing the text
       @param len   number of characters in the text
     */
    virtual void text(const sal_uInt8 * data, size_t len) = 0;

    /**
       Receives 16-bit per character text.

       @param data    buffer containing the text
       @param len     number of characters in the text.
     */
    virtual void utext(const sal_uInt8 * data, size_t len) = 0;

    /**
     * Offset in EMUs for a shape.
     *
     * Call *before* an ooxml::CT_PosH/V_posOffset sprm is sent.
     */
    virtual void positionOffset(const OUString& rText, bool bVertical) = 0;
    /// Returns the last set offsets of a shape in HMM.
    virtual css::awt::Point getPositionOffset() = 0;
    /**
     * Horizontal and vertical alignment for a shape.
     *
     * Call *before* an ooxml:CT_PosH/V_align sprm is sent.
     */
    virtual void align(const OUString& rText, bool bVertical) = 0;
    virtual void positivePercentage(const OUString& rText) = 0;

    /**
       Receives properties of the current run of text.

       @param ref    reference to the properties
     */
    virtual void props(writerfilter::Reference<Properties>::Pointer_t ref) = 0;

    /**
       Receives table.

       @param name     name of the table
       @param ref      referecne to the table
     */
    virtual void table(Id name,
                       writerfilter::Reference<Table>::Pointer_t ref) = 0;

    /**
        Receives a substream.

        @param name    name of the substream
        @param ref     reference to the substream
    */
    virtual void substream(Id name,
                           writerfilter::Reference<Stream>::Pointer_t ref) = 0;


    /**
       Debugging: Receives information about current point in stream.

       @param info     the information
     */
    virtual void info(const std::string & info) = 0;

protected:
    ~Stream() {}
};

/**
   A value.

   The methods of this class may throw exceptions if a certain aspect
   makes no sense for a certain value, e.g. the integer value of a
   string.
 */
class Value
{
public:
    /**
       Pointer to a value.
     */
    typedef std::unique_ptr<Value> Pointer_t;

    virtual ~Value() {}

    /**
       Returns integer representation of the value.
     */
    virtual int getInt() const = 0;

    /**
       Returns string representation of the value.
     */
    virtual OUString getString() const = 0;

    /**
       Returns representation of the value as uno::Any.
     */
    virtual css::uno::Any getAny() const = 0;

    /**
       Returns properties of this value.
     */
    virtual writerfilter::Reference<Properties>::Pointer_t getProperties() = 0;

    /**
       Returns binary object  of this value.
     */
    virtual writerfilter::Reference<BinaryObj>::Pointer_t getBinary() = 0;

    /**
       Returns string representation of this value.
     */
#ifdef DEBUG_WRITERFILTER
    virtual std::string toString() const = 0;
#endif
};

/**
   An SPRM: Section, Paragraph and Run Modifier

 */
class Sprm
{
public:
    typedef std::unique_ptr<Sprm> Pointer_t;

    /**
       Returns id of the SPRM.
     */
    virtual sal_uInt32 getId() const = 0;

    /**
       Returns value of the SPRM.
     */
    virtual Value::Pointer_t getValue() = 0;

    /**
       Returns reference to properties contained in the SPRM.

     */
    virtual writerfilter::Reference<Properties>::Pointer_t getProps() = 0;

    /**
       Returns name of sprm.
    */
#ifdef DEBUG_WRITERFILTER
    virtual std::string getName() const = 0;
#endif

    /**
       Returns string representation of sprm.
     */
#ifdef DEBUG_WRITERFILTER
    virtual std::string toString() const = 0;
#endif

protected:
    ~Sprm() {}
};

typedef sal_Int32 Token_t;

}

#endif // INCLUDED_WRITERFILTER_INC_DMAPPER_RESOURCEMODEL_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
