/***********************************************************************************

    Copyright (C) 2007-2020 Ahmet Öztürk (aoz_2@yahoo.com)

    This file is part of Lifeograph.

    Lifeograph 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.

    Lifeograph 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 Lifeograph.  If not, see <http://www.gnu.org/licenses/>.

***********************************************************************************/


#ifndef LIFEOGRAPH_CHAPTER_HEADER
#define LIFEOGRAPH_CHAPTER_HEADER


#include <set>
#include <map>
#include <vector>
#include <limits>

#include "helpers.hpp"  // i18n headers
#include "entry.hpp"


namespace LIFEO
{

using namespace HELPERS;

// CHAPTER =========================================================================================
class Chapter : public Entry, public SetEntries
{
    public:
                                Chapter( Diary* const, date_t, ElemStatus = ES::CHAPTER_DEFAULT );
        // this class should have a virtual dtor for some reason because
        // if it does not, its derived classes cannot be deleted
        virtual                 ~Chapter() {}

        SKVVec                  get_as_skvvec() const override;

        Ustring                 get_date_str() const;

        void                    set_date( date_t date ) override
        { if( ! Date::is_ordinal( date ) ) m_date.m_date = date; }

        Type                    get_type() const override
        { return ET_CHAPTER; }

        const Icon&             get_icon() const override;
        const Icon&             get_icon32() const override;

        Ustring                 get_list_str() const;

        void                    set_ctg( CategoryChapters* ctg )
        { m_p2ctg = ctg; }
        CategoryChapters*       get_ctg() const
        { return m_p2ctg; }

        date_t                  get_free_order() const;

        void                    recalculate_span( const Chapter* );
        int                     get_time_span() const
        { return m_time_span; }
        void                    set_time_span( int s )
        { m_time_span = s; }

        Color                   get_color() const
        { return m_color; }
        void                    set_color( Color&& color )
        { m_color = color; }

        int                     get_entry_count() const
        { return SetEntries::size(); }

    protected:
        int                     m_time_span{ 0 };
        Color                   m_color{ "White" };
        CategoryChapters*       m_p2ctg{ nullptr };

    friend class CategoryChapters;
    friend class ChapterView;
};

class CategoryChapters :
        public DiaryElement, public std::map< date_t, Chapter*, FuncCompareDates >
{
    public:
        explicit                CategoryChapters( Diary* const, const Ustring& );
        virtual                 ~CategoryChapters();

        Type                    get_type() const override
        { return ET_CHAPTER_CTG; }
        virtual int             get_size() const override
        { return size(); }

        date_t                  get_date_t() const override;

        Chapter*                get_chapter_at( const date_t ) const;
        Chapter*                get_chapter_around( const date_t ) const;

        Chapter*                create_chapter( const date_t, bool, bool, bool );
        bool                    set_chapter_date( Chapter*, date_t );

        void                    clear();

    protected:
        bool                    add( Chapter* );
};

class PoolCategoriesChapters :
        public std::map< Ustring, CategoryChapters*, FuncCmpStrings >
{
    public:
                                //PoolCategoriesChapters() {}
                                ~PoolCategoriesChapters();
        void                    clear();
        Chapter*                get_chapter( const Ustring&, const date_t ) const;
        CategoryChapters*       get_ctg( const Ustring& ) const;
};

} // end of namespace LIFEO

#endif
