/************************************************************************
**
**  Copyright (C) 2015, 2016  Kevin B. Hendricks Stratford, ON, Canada 
**  Copyright (C) 2009, 2010, 2011  Strahinja Markovic  <strahinja.markovic@gmail.com>
**
**  This file is part of Sigil.
**
**  Sigil is free software: you can redistribute it and/or modify
**  it under the terms of the GNU General Public License as published by
**  the Free Software Foundation, either version 3 of the License, or
**  (at your option) any later version.
**
**  Sigil 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 General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with Sigil.  If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/

#pragma once
#ifndef HEADINGS_H
#define HEADINGS_H

#include <QtCore/QList>
#include <QtCore/QMetaType>


class HTMLResource;
class QString;

class Headings
{

public:

    // Describes a heading element found
    // in the XHTML source code
    struct Heading {
        // The HTMLResource file the heading belongs to
        HTMLResource *resource_file;

        QList<unsigned int> path_to_node;

        // Represents what the heading should
        // look like in the TOC.
        QString text;

        // Represents the current title attribute if any
        QString title;
        QString orig_title;

        // The level of the heading, from 1 to 6
        // (lower number means 'bigger' heading )
        int level;
        int orig_level;
        
        QString id;

        // True if the heading appears within
        // 20 lines after the body tag
        // (only one heading per file)
        bool at_file_start;

        // Should the heading be included in the TOC or not
        bool include_in_toc;

        // The headings 'below' this one
        // (those that appear after it in the source and
        // are of higher level/smaller size)
        QList<Heading> children;

        // Have we made a change to the document using the TOC dialog
        bool is_changed;
    };

    // A wrapper struct for the pointer
    // because of restrictions on what
    // can be stored inside a QVariant
    struct HeadingPointer {
        Heading *heading;
    };


    // Returns a list of headings from the provided XHTML source;
    // the list is flat, the headings are *not* in a hierarchy tree.
    // Set include_unwanted_headings to true to get headings that the
    // user has marked as unwanted.
    static QList<Heading> GetHeadingList(QList<HTMLResource *> html_resources,
                                         bool include_unwanted_headings = false);

    static QList<Heading> GetHeadingListForOneFile(HTMLResource *html_resource,
            bool include_unwanted_headings = false);

    // Takes a flat list of headings and returns a list with those
    // headings sorted into a hierarchy
    static QList<Heading> MakeHeadingHeirarchy(const QList<Heading> &headings);

    // Takes a hierarchical list of headings and converts it into a flat list
    static QList<Heading> GetFlattenedHeadings(const QList<Heading> &headings);

private:
    // Flattens the provided heading node and its children
    // into a list and returns it
    static QList<Heading> FlattenHeadingNode(Heading heading);

    // Adds the new_child heading to the parent heading;
    // the new_child is propagated down the tree if necessary
    static void AddChildHeading(Heading &parent, Heading new_child);
};


// Enables us to store instances of the
// HeadingPointer struct inside of QVariants
Q_DECLARE_METATYPE(Headings::HeadingPointer);


#endif // HEADINGS_H


