/*
    This file is part of Msc-generator.
    Copyright (C) 2008-2024 Zoltan Turanyi
    Distributed under GNU Affero General Public License.

    Msc-generator is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Msc-generator 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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with Msc-generator.  If not, see <http://www.gnu.org/licenses/>.
*/

/** @file mscattribute.h Note attrbiues.
* @ingroup libmscgen_files */


#ifndef MSCATTRIBUTE_H
#define MSCATTRIBUTE_H
#include "cgen_attribute.h"

namespace msc {

class MscChart;

/** Stores the properties of notes (pointer type and position; width).*/
struct NoteAttr
{
public:
    /** Enumerate the types of pointers notes may have.*/
    enum EPointerType { POINTER_INVALID = 0, NONE, CALLOUT, ARROW, BLOCKARROW };
    /** Enumerates the types of positions the note may be attributed with.*/
    enum EPosType { POS_INVALID = 0, POS_NEAR, POS_FAR, LEFT, RIGHT, UP, DOWN, LEFT_UP, LEFT_DOWN, RIGHT_UP, RIGHT_DOWN };
    OptAttr<EPointerType> pointer; ///<What pointers shall the note have
    OptAttr<int> def_float_dist;   ///<What distance pos attribute the note has (near=-1, far=1)
    OptAttr<int> def_float_x;      ///<What horizontal pos attribute the note has (left=-1, right=+1) 
    OptAttr<int> def_float_y;      ///<What vertical pos attribute the note has (top=-1, bottom=+1)
    WidthAttr width; ///<The width specified by the used. second<0 means the string contains the width
    NoteAttr() { Empty(); MakeComplete(); } ///<Create a fully specified note style with default values (Callout type, no specific position preference.)
    void Empty() { pointer.reset(); def_float_dist.reset(); def_float_x.reset(); def_float_y.reset(); width.Empty(); } ///<Clear all content from the note style.
    bool IsEmpty() const noexcept { return !pointer && !def_float_dist && !def_float_x && !def_float_y && width.IsEmpty(); } ///<True if none of the note attributes are set. 
    void MakeComplete();
    bool IsComplete() const { return pointer && def_float_dist && def_float_x && def_float_y && !width.IsEmpty(); } ///<True if all of the note attributes are set. 
    NoteAttr &operator +=(const NoteAttr&a); ///<Applies `a` to us: sets all our attributes, which are set in `a` to the value in `a`; leaves the rest unchanged.
    bool operator == (const NoteAttr &a) const;
    virtual bool AddAttribute(const Attribute &a, MscChart *chart, EStyleType t);
    static void AttributeNames(Csh &csh);
    static bool AttributeValues(std::string_view attr, Csh &csh);
    string Print(int indent = 0) const;
    static bool CshHintGraphicCallbackForLayout(Canvas *canvas, CshHintGraphicParam p, CshHintStore &);
    static bool CshHintGraphicCallbackForPointer(Canvas *canvas, CshHintGraphicParam p, CshHintStore &);
    static bool CshHintGraphicCallbackForPos(Canvas *canvas, CshHintGraphicParam p, CshHintStore &);
};

} //namespace


#endif