/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * 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/.
 */

#ifndef INCLUDED_ORCUS_TYPES_HPP
#define INCLUDED_ORCUS_TYPES_HPP

#include <cstdlib>
#include <vector>
#include <string>
#include "pstring.hpp"
#include "env.hpp"

namespace orcus {

// XML specific types

typedef size_t xml_token_t;
typedef const char* xmlns_id_t;

ORCUS_PSR_DLLPUBLIC extern const xmlns_id_t XMLNS_UNKNOWN_ID;
ORCUS_PSR_DLLPUBLIC extern const xml_token_t XML_UNKNOWN_TOKEN;
ORCUS_PSR_DLLPUBLIC extern const size_t index_not_found;
ORCUS_PSR_DLLPUBLIC extern const size_t unspecified;

struct xml_name_t
{
    xmlns_id_t ns;
    pstring name;

    xml_name_t() : ns(XMLNS_UNKNOWN_ID), name() {}
    xml_name_t(xmlns_id_t _ns, const pstring& _name) : ns(_ns), name(_name) {}
    xml_name_t(const xml_name_t& r) : ns(r.ns), name(r.name) {}
};

struct ORCUS_PSR_DLLPUBLIC xml_token_attr_t
{
    xmlns_id_t ns;
    xml_token_t name;
    pstring raw_name;
    pstring value;

    /**
     * Whether or not the attribute value is transient. A transient value is
     * only guaranteed to be valid until the end of the start_element call,
     * after which its validity is not guaranteed. A non-transient value is
     * guaranteed to be valid during the life cycle of the xml stream it
     * belongs to.
     */
    bool transient;

    xml_token_attr_t();
    xml_token_attr_t(
        xmlns_id_t _ns, xml_token_t _name, const pstring& _value, bool _transient);
    xml_token_attr_t(
        xmlns_id_t _ns, xml_token_t _name, const pstring& _raw_name,
        const pstring& _value, bool _transient);
};

/**
 * Element properties passed to its handler via start_element() and
 * end_element() calls.
 */
struct ORCUS_PSR_DLLPUBLIC xml_token_element_t
{
    xmlns_id_t ns;
    xml_token_t name;
    pstring raw_name;
    std::vector<xml_token_attr_t> attrs;

    xml_token_element_t& operator= (xml_token_element_t) = delete;

    xml_token_element_t();
    xml_token_element_t(xmlns_id_t _ns, xml_token_t _name, const pstring& _raw_name, std::vector<xml_token_attr_t>&& _attrs);
    xml_token_element_t(const xml_token_element_t& other);
    xml_token_element_t(xml_token_element_t&& other);
};

// Other types

enum class length_unit_t
{
    unknown = 0,
    centimeter,
    millimeter,
    xlsx_column_digit,
    inch,
    point,
    twip,
    pixel

    // TODO: Add more.
};

enum class format_t
{
    unknown = 0,
    ods,
    xlsx,
    gnumeric,
    xls_xml,
    csv
};

struct ORCUS_DLLPUBLIC length_t
{
    length_unit_t unit;
    double value;

    length_t();

    std::string to_string() const;
};

struct ORCUS_DLLPUBLIC date_time_t
{
    int year;
    int month;
    int day;
    int hour;
    int minute;
    double second;

    date_time_t();
    date_time_t(int _year, int _month, int _day);
    date_time_t(int _year, int _month, int _day, int _hour, int _minute, double _second);
    date_time_t(const date_time_t& other);
    ~date_time_t();

    date_time_t& operator= (date_time_t other);

    bool operator== (const date_time_t& other) const;
    bool operator!= (const date_time_t& other) const;

    std::string to_string() const;

    void swap(date_time_t& other);
};

ORCUS_DLLPUBLIC std::ostream& operator<< (std::ostream& os, const date_time_t& v);

typedef ::std::vector<xml_token_attr_t> xml_attrs_t;

}

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