/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

/** @#file
 *
 *  XML import of all variable related text fields plus database display field
 */

#ifndef _XMLOFF_TXTVFLDI_HXX
#define _XMLOFF_TXTVFLDI_HXX

#include <bf_xmloff/txtvfldi.hxx>

#include <bf_xmloff/txtfldi.hxx>

#include <com/sun/star/beans/XPropertySet.hpp>

#include <com/sun/star/beans/XPropertySetInfo.hpp>
namespace binfilter {

/// variable type (for XMLSetVarFieldImportContext)
enum VarType
{
    VarTypeSimple,
    VarTypeUserField,
    VarTypeSequence
};

/** helper class: parses value-type and associated value attributes */
class XMLValueImportHelper
{

    const ::rtl::OUString sPropertyContent;
    const ::rtl::OUString sPropertyValue;
    const ::rtl::OUString sPropertyFormula;
    const ::rtl::OUString sPropertyNumberFormat;
    const ::rtl::OUString sPropertyIsFixedLanguage;

    SvXMLImport& rImport;
    XMLTextImportHelper& rHelper;

    ::rtl::OUString sValue;     /// string value (only valid if bStringValueOK)
    double fValue;              /// double value (only valid if bFloatValueOK)
    sal_Int32 nFormatKey;       /// format key (only valid of bFormatOK)
    ::rtl::OUString sFormula;   /// formula string
    ::rtl::OUString sDefault;   /// default (see bStringDefault/bFormulaDef.)
    sal_Bool bIsDefaultLanguage;/// format (of nFormatKey) has system language?

    sal_Bool bStringType;       /// is this a string (or a float) type?
    sal_Bool bFormatOK;         /// have we read a style:data-style-name attr.?
    sal_Bool bTypeOK;           /// have we read a value-type attribute?
    sal_Bool bStringValueOK;    /// have we read a string-value attr.?
    sal_Bool bFloatValueOK;     /// have we read any of the float attr.s?
    sal_Bool bFormulaOK;        /// have we read the formula attribute?

    const sal_Bool bSetType;    /// should PrepareField set the SetExp subtype?
    const sal_Bool bSetValue;   /// should PrepareField set content/value?
    const sal_Bool bSetStyle;   /// should PrepareField set NumberFormat?
    const sal_Bool bSetFormula; /// should PrepareField set Formula?

    const sal_Bool bStringDefault;  /// default: string-value = content
    const sal_Bool bFormulaDefault; /// default: formula = content

public:
    XMLValueImportHelper(
        SvXMLImport& rImprt,                    /// XML Import
        XMLTextImportHelper& rHlp,              /// text import helper
        sal_Bool bType,                         /// process type (PrepareField)
        sal_Bool bStyle,                        /// process data style (P.F.)
        sal_Bool bValue,                        /// process value (Prep.Field)
        sal_Bool bFormula);                     /// process formula (Prep.F.)

    virtual ~XMLValueImportHelper() {}

    /// process attribute values
    virtual void ProcessAttribute( sal_uInt16 nAttrToken,
                                   const ::rtl::OUString& sAttrValue );

    /// prepare XTextField for insertion into document
    virtual void PrepareField(
        const ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet> & xPropertySet);

    /// is value a string (rather than double)?
    inline sal_Bool IsStringValue() { return bStringType; }

    /// has format been read?
    inline sal_Bool IsFormatOK() { return bFormatOK; }

    inline void SetDefault(const ::rtl::OUString& sStr) { sDefault = sStr; }
};

/**
 * abstract parent class for all variable related fields
 * - variable-set/get/decl      (not -decls),
 * - user-field-get/decl        (not -decls),
 * - sequence/-decl             (not -decls),
 * - expression,
 * - text-input
 *
 * Processes the following attributes:
 * - name
 * - formula
 * - display
 * - value, value-type, data-style-name (via XMLValueImportHelper)
 * - description.
 *
 * Each attribute has a corresponding member, a bool variable to indicate
 * whether it was set or not, and a bool variable whether it should be set
 * using the standard property name.
 *
 * bValid is set true, when name is found!
 * (Most variable related fields are valid, if a name is
 * found. However, some are always valid. In this case, setting bValid
 * does not matter.)
 */
class XMLVarFieldImportContext : public XMLTextFieldImportContext
{
protected:
    const ::rtl::OUString sPropertyContent;
    const ::rtl::OUString sPropertyHint;
    const ::rtl::OUString sPropertyIsVisible;
    const ::rtl::OUString sPropertyIsDisplayFormula;
//STRIP013  const ::rtl::OUString sPropertyCurrentPresentation;

private:
    ::rtl::OUString sName;              /// name attribute
    ::rtl::OUString sFormula;           /// formula attribute
    ::rtl::OUString sDescription;       /// description
    XMLValueImportHelper aValueHelper;  /// value, value-type, and style
    sal_Bool bDisplayFormula;           /// display formula?(rather than value)
    sal_Bool bDisplayNone;              /// hide field?

    sal_Bool bNameOK;                   /// sName was set
    sal_Bool bFormulaOK;                /// sFormula was set
    sal_Bool bDescriptionOK;            /// sDescription was set
    sal_Bool bDisplayOK;                /// sDisplayFormula/-None were set

    sal_Bool bSetName;                  /// set sName with ???-property
    sal_Bool bSetFormula;               /// set Formula property
    sal_Bool bSetFormulaDefault;        /// use content as default for formula
    sal_Bool bSetDescription;           /// set sDescription with Hint-property
    sal_Bool bSetVisible;               /// set IsVisible
    sal_Bool bSetDisplayFormula;        /// set DisplayFormula (sub type???)
//STRIP013  sal_Bool bSetPresentation;          /// set presentation frm elem. content?

public:

    TYPEINFO();

    XMLVarFieldImportContext(
        // for XMLTextFieldImportContext:
        SvXMLImport& rImport,           /// XML Import
        XMLTextImportHelper& rHlp,      /// text import helper
        const sal_Char* pServiceName,   /// name of SO API service
        sal_uInt16 nPrfx,               /// namespace prefix
        const ::rtl::OUString& rLocalName,  /// element name w/o prefix
        // config variables for PrepareField behavior:
        sal_Bool bName,                 /// set sName with ???-property
        sal_Bool bFormula,              /// set Formula property
        sal_Bool bFormulaDefault,       /// use content as default for formula
        sal_Bool bDescription,          /// set sDescription with Hint-property
        sal_Bool bVisible,              /// set IsVisible (display attr)
        sal_Bool bDisplayFormula,       /// set ??? (display attr.)
        sal_Bool bType,                 /// set value type with ???-property
        sal_Bool bStyle,                /// set data style (NumberFormat-Prop.)
        sal_Bool bValue);               /// set value with Content/Value-Prop.
//STRIP013      ,sal_Bool bPresentation);       /// set presentation from elem. content

protected:
    /// process attribute values
    virtual void ProcessAttribute( sal_uInt16 nAttrToken,
                                   const ::rtl::OUString& sAttrValue );

    /// prepare XTextField for insertion into document
    virtual void PrepareField(
        const ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet> & xPropertySet);

    // various accessor methods:
    inline ::rtl::OUString GetName()    { return sName; }
    inline sal_Bool IsStringValue()     { return aValueHelper.IsStringValue();}
    inline sal_Bool IsNameOK()          { return bNameOK; }
    inline sal_Bool IsFormulaOK()       { return bFormulaOK; }
    inline sal_Bool IsDescriptionOK()   { return bDescriptionOK; }
    inline sal_Bool IsDisplayOK()       { return bDisplayOK; }
};

/** import variable get fields (<text:variable-get>) */
class XMLVariableGetFieldImportContext : public XMLVarFieldImportContext
{
    const ::rtl::OUString sPropertySubType;

public:

    TYPEINFO();

    XMLVariableGetFieldImportContext(
        SvXMLImport& rImport,                   /// XML Import
        XMLTextImportHelper& rHlp,              /// Text import helper
        sal_uInt16 nPrfx,                       /// namespace prefix
        const ::rtl::OUString& rLocalName);     /// element name w/o prefix

protected:
    /// prepare XTextField for insertion into document
    virtual void PrepareField(
        const ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet> & xPropertySet);
};

/** import expression fields (<text:expression>) */
class XMLExpressionFieldImportContext : public XMLVarFieldImportContext
{
    const ::rtl::OUString sPropertySubType;

public:

    TYPEINFO();

    XMLExpressionFieldImportContext(
        SvXMLImport& rImport,                   /// XML Import
        XMLTextImportHelper& rHlp,              /// Text import helper
        sal_uInt16 nPrfx,                       /// namespace prefix
        const ::rtl::OUString& sLocalName);     /// element name w/o prefix

protected:
    virtual void PrepareField(
        const ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet> & xPropertySet);
};

/*** import text input fields (<text:text-input>) */
class XMLTextInputFieldImportContext : public XMLVarFieldImportContext
{
    const ::rtl::OUString sPropertyContent;

public:

    TYPEINFO();

    XMLTextInputFieldImportContext(
        SvXMLImport& rImport,                   /// XML Import
        XMLTextImportHelper& rHlp,              /// Text import helper
        sal_uInt16 nPrfx,                       /// namespace prefix
        const ::rtl::OUString& sLocalName);     /// element name w/o prefix

protected:
    virtual void PrepareField(
        const ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet> & xPropertySet);
};

/**
 * uperclass for variable/user-set, var/user-input, and sequence fields
 * inds field master of appropriate type and attaches field to it.
 */
class XMLSetVarFieldImportContext : public XMLVarFieldImportContext
{
    const VarType eFieldType;

public:

    TYPEINFO();

    XMLSetVarFieldImportContext(
        // for XMLTextFieldImportContext:
        SvXMLImport& rImport,           /// see XMLTextFieldImportContext
        XMLTextImportHelper& rHlp,      /// see XMLTextFieldImportContext
        const sal_Char* pServiceName,   /// see XMLTextFieldImportContext
        sal_uInt16 nPrfx,               /// see XMLTextFieldImportContext
        const ::rtl::OUString& rLocalName, /// see XMLTextFieldImportContext
        // for finding appropriate field master (see EndElement())
        VarType eVarType,               /// variable type
        // config variables:
        sal_Bool bName,                 /// see XMLTextFieldImportContext
        sal_Bool bFormula,              /// see XMLTextFieldImportContext
        sal_Bool bFormulaDefault,       /// see XMLTextFieldImportContext
        sal_Bool bDescription,          /// see XMLTextFieldImportContext
        sal_Bool bVisible,              /// see XMLTextFieldImportContext
        sal_Bool bDisplayFormula,       /// see XMLTextFieldImportContext
        sal_Bool bType,                 /// see XMLTextFieldImportContext
        sal_Bool bStyle,                /// see XMLTextFieldImportContext
        sal_Bool bValue);               /// see XMLTextFieldImportContext
//STRIP013      ,sal_Bool bPresentation);       /// see XMLTextFieldImportContext

protected:

    /// create XTextField, attach master and insert into document;
    /// also calls PrepareTextField
    virtual void EndElement();

    /// find appropriate field master
    sal_Bool FindFieldMaster(
        ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet> & xMaster);
};

/** import variable set fields (<text:variable-set>) */
class XMLVariableSetFieldImportContext : public XMLSetVarFieldImportContext
{
    const ::rtl::OUString sPropertySubType;

public:

    TYPEINFO();

    XMLVariableSetFieldImportContext(
        SvXMLImport& rImport,                   /// XML Import
        XMLTextImportHelper& rHlp,              /// Text import helper
        sal_uInt16 nPrfx,                       /// namespace prefix
        const ::rtl::OUString& rLocalName);     /// element name w/o prefix

protected:
    /// prepare XTextField for insertion into document
    virtual void PrepareField(
        const ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet> & xPropertySet);
};

/** variable input fields (<text:variable-input>) */
class XMLVariableInputFieldImportContext : public XMLSetVarFieldImportContext
{
    const ::rtl::OUString sPropertySubType;
    const ::rtl::OUString sPropertyIsInput;

public:

    TYPEINFO();

    XMLVariableInputFieldImportContext(
        SvXMLImport& rImport,                   /// XML Import
        XMLTextImportHelper& rHlp,              /// Text import helper
        sal_uInt16 nPrfx,                       /// namespace prefix
        const ::rtl::OUString& rLocalName);     /// element name w/o prefix

protected:

    /// prepare XTextField for insertion into document
    virtual void PrepareField(
        const ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet> & xPropertySet);
};

/** user fields (<text:user-field-get>) */
class XMLUserFieldImportContext : public XMLSetVarFieldImportContext
{

public:

    TYPEINFO();

    XMLUserFieldImportContext(
        SvXMLImport& rImport,                   /// XML Import
        XMLTextImportHelper& rHlp,              /// Text import helper
        sal_uInt16 nPrfx,                       /// namespace prefix
        const ::rtl::OUString& rLocalName);     /// element name w/o prefix
};

/** user input fields (<text:user-field-input>) */
class XMLUserFieldInputImportContext : public XMLVarFieldImportContext
{

public:

    TYPEINFO();

    XMLUserFieldInputImportContext(
        SvXMLImport& rImport,                   /// XML Import
        XMLTextImportHelper& rHlp,              /// Text import helper
        sal_uInt16 nPrfx,                       /// namespace prefix
        const ::rtl::OUString& rLocalName);     /// element name w/o prefix

    virtual void PrepareField(
        const ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet> & xPropertySet);
};

/** sequence fields (<text:sequence>) */
class XMLSequenceFieldImportContext : public XMLSetVarFieldImportContext
{
    const ::rtl::OUString sPropertyFormula;
    const ::rtl::OUString sPropertyNumberFormat;
    const ::rtl::OUString sPropertySequenceValue;
    ::rtl::OUString sFormula;
    ::rtl::OUString sNumFormat;
    ::rtl::OUString sNumFormatSync;
    ::rtl::OUString sRefName;

    sal_Bool bRefNameOK;

public:

    TYPEINFO();

    XMLSequenceFieldImportContext(
        SvXMLImport& rImport,                   /// XML Import
        XMLTextImportHelper& rHlp,              /// Text import helper
        sal_uInt16 nPrfx,                       /// namespace prefix
        const ::rtl::OUString& rLocalName);     /// element name w/o prefix

protected:

    /// process attribute values
    virtual void ProcessAttribute( sal_uInt16 nAttrToken,
                                   const ::rtl::OUString& sAttrValue );

    /// prepare XTextField for insertion into document
    virtual void PrepareField(
        const ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet> & xPropertySet);
};

/**
 * variable declaration container for all variable fields
 *      (variable-decls, user-field-decls, sequence-decls)
 */
class XMLVariableDeclsImportContext : public SvXMLImportContext
{
    enum VarType eVarDeclsContextType;
    XMLTextImportHelper& rImportHelper;

public:

    TYPEINFO();

    XMLVariableDeclsImportContext(
        SvXMLImport& rImport,                   /// XML Import
        XMLTextImportHelper& rHlp,              /// text import helper
        sal_uInt16 nPrfx,                       /// namespace prefix
        const ::rtl::OUString& rLocalName,      /// element name w/o prefix
        enum VarType eVarType);                 /// variable type

    virtual SvXMLImportContext *CreateChildContext(
        sal_uInt16 nPrefix,
        const ::rtl::OUString& rLocalName,
        const ::com::sun::star::uno::Reference<
        ::com::sun::star::xml::sax::XAttributeList> & xAttrList );
};

/**
 * variable field declarations
 *      (variable-decl, user-field-decl, sequence-decl)
 */
class XMLVariableDeclImportContext : public SvXMLImportContext
{
    const ::rtl::OUString sPropertyName;
    const ::rtl::OUString sPropertySubType;
    const ::rtl::OUString sPropertyNumberingLevel;
    const ::rtl::OUString sPropertyNumberingSeparator;
    const ::rtl::OUString sPropertyIsExpression;

    ::rtl::OUString sName;
    XMLValueImportHelper aValueHelper;
    sal_Int8 nNumLevel;
    sal_Unicode cSeparationChar;

public:

    TYPEINFO();

    XMLVariableDeclImportContext(
        SvXMLImport& rImport,                   /// XML Import
        XMLTextImportHelper& rHlp,              /// text import helper
        sal_uInt16 nPrfx,                       /// namespace prefix
        const ::rtl::OUString& rLocalName,      /// element name w/o prefix
        const ::com::sun::star::uno::Reference< /// list of element attributes
        ::com::sun::star::xml::sax::XAttributeList> & xAttrList,
        enum VarType eVarType);                 /// variable type

    /// get field master for name and rename if appropriate
    static sal_Bool FindFieldMaster(::com::sun::star::uno::Reference<
                                    ::com::sun::star::beans::XPropertySet> & xMaster,
                                    SvXMLImport& rImport,
                                    XMLTextImportHelper& rHelper,
                                    const ::rtl::OUString& sVarName,
                                    enum VarType eVarType);
};

/** import table formula fields (deprecated; for Writer 2.0 compatibility) */
class XMLTableFormulaImportContext : public XMLTextFieldImportContext
{
    const ::rtl::OUString sPropertyNumberFormat;
    const ::rtl::OUString sPropertyContent;
    const ::rtl::OUString sPropertyIsShowFormula;
//STRIP013  const ::rtl::OUString sPropertyCurrentPresentation;

    XMLValueImportHelper aValueHelper;

    ::rtl::OUString sFormula;
    sal_Bool bFormulaOK;

    sal_Bool bIsShowFormula;

public:

    TYPEINFO();

    XMLTableFormulaImportContext(
        SvXMLImport& rImport,                   /// XML Import
        XMLTextImportHelper& rHlp,              /// text import helper
        sal_uInt16 nPrfx,                       /// namespace prefix
        const ::rtl::OUString& rLocalName);     /// element name w/o prefix
    virtual ~XMLTableFormulaImportContext();

protected:

    /// process attribute values
    virtual void ProcessAttribute( sal_uInt16 nAttrToken,
                                   const ::rtl::OUString& sAttrValue );

    /// prepare XTextField for insertion into document
    virtual void PrepareField(
        const ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet> & xPropertySet);
};

/** import database display fields (<text:database-display>) */
class XMLDatabaseDisplayImportContext : public XMLDatabaseFieldImportContext
{
    const ::rtl::OUString sPropertyColumnName;
    const ::rtl::OUString sPropertyDatabaseFormat;
//STRIP013  const ::rtl::OUString sPropertyCurrentPresentation;
    const ::rtl::OUString sPropertyIsVisible;

    XMLValueImportHelper aValueHelper;

    ::rtl::OUString sColumnName;
    sal_Bool bColumnOK;

    sal_Bool bDisplay;
    sal_Bool bDisplayOK;

public:

    TYPEINFO();

    XMLDatabaseDisplayImportContext(
        SvXMLImport& rImport,                   /// XML Import
        XMLTextImportHelper& rHlp,              /// text import helper
        sal_uInt16 nPrfx,                       /// namespace prefix
        const ::rtl::OUString& rLocalName);     /// element name w/o prefix

protected:

    /// process attribute values
    virtual void ProcessAttribute( sal_uInt16 nAttrToken,
                                   const ::rtl::OUString& sAttrValue );

    /// create, prepare and insert database field master and database field
    virtual void EndElement();
};

}//end of namespace binfilter
#endif

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