// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

#pragma once

/**

 \file

 # %CSSStyle

 A CSSStyle object represents a set of rules in a CSS stylesheet which all have a common **base
 selector**, consisting of an element name and optional class name (e.g. `h1` or `h1.Appendix`). The
 base selector is used to identify the style in a CSSSheet object, and is passed to
 CSSSheetLookupSelector() to add or retrieve a particular style.

 Each CSSStyle object has one or more **rules** associated with it. A rule is identified by its
 **suffix**, which is the text that comes immediately after the base selector in the textual
 representation of the stylesheet. For example, a rule defined in a CSS stylesheet with a selector
 of `h1.Appendix::before` would have a base selector of `h1.Appendix`, and a suffix of `::before`.

 In the typical case, a style will have only a single rule with an empty suffix, and this rule will
 define all of the properties of that style. For example, a style with a base selector of `p.Warning`
 and properties defining the color and font size would appear in the textual representation of the
 stylesheet like this:

     p.Warning {
         color: red;
         font-size: 18pt;
     }

 In other cases, a style may have multiple rules, each with a different suffix. Each rule defines
 the properties to be applied to a certain aspect of that element, such as particular rows of a
 table. For example, style with a base selector of `table.Statistics` which defines a black border,
 and colors odd rows blue and odd rows red, would have three separate rules:

     table.Statistics {
         border: 1px solid black;
     }

     table.Statistics > * > tr:nth-of-type(odd) > td {
         color: blue;
     }

     table.Statistics > * > tr:nth-of-type(even) > td {
         color: red;
     }

 ## Creating styles

 You should not create CSSStyle objects directly --- instead, call CSSSheetLookupSelector() with
 the `add` parameter set to 1. This ensures that if there is already a style with that selector
 present in the stylesheet, you will not end up with a duplicate. CSSSheetLookupSelector() returns
 the new or existing style, and calls CSSStyleNew() internally if necessary.

 All though CSSStyle objects are reference-counted, you generally do not need to retain or release
 them yourself, as the CSSSheet object itself maintains a reference to all styles within it. When
 a CSSSheet object is freed, it releases all references to the styles it contains, so assuming there
 are no additional references to them, they will be freed at that time as well.

 ## Working with rules

 A rule is represented by a CSSProperties object. The main function for accessing rules is
 CSSStyleRuleForSuffix(), which requires the desired suffix to be specified. There are also several
 short-hand funcitons for obtaining certain commonly-used rules; CSSStyleRule() returns the default
 rule (the one with an empty suffix), while CSSStyleCell() and CSSStyleBefore() returns the rules
 for table cells and content displayed before an element, respectively.

 When you call any of these functions and the rule does not exist, it is created. When the
 stylesheet is converted to its textual representation using CSSSheetCopyCSSText(), empty rules
 (those with no properties) are excluded --- so it is never necessary to remove a rule as such.
 You can, however, clear all the properties on it, which will have the same effect.

 ## Style inheritance

 To support working with documents in formats like docx and ODF, which support style inheritance, we
 use the special `-uxwrite-parent` CSS property to record the base selector of the parent style, if
 any. This should not be set directly, however, as some characters in the style name may not be
 valid in CSS values. Instead, the parent value is stored as a quoted string, according to the
 escaping rules defined in the CSS specification. You should always use CSSStyleCopyParent() and
 CSSStyleSetParent() to access this property; as this handles quoting for you.

 Note that since CSSStyle objects do not contain direct references to each other or the stylesheet
 in which they are contained, if you want to obtain the actual CSSStyle object representing the
 parent style, you need to do so from the CSSSheet object. This can be done using
 CSSSheetParentOfStyle().

 ## Style for next paragraph

 Microsoft Word and OpenOffice both allow a style to specify which style should be used for the next
 paragraph, if the user presses enter within a paragraph of the given style. For example, it is
 typical for heading styles to specify "Normal" as the next style, so when a user types in a heading
 and presses enter, the program adds a normal paragraph, instead of another heading.

 As with parent styles, we use a special property to record this, `-uxwrite-next`. The UX Write
 editing code knows about this property, and uses it to determine what style to associate with
 newly-created paragraphs after enter is pressed. As with the `-uxwrite-parent` property, this
 needs to be quoted, and you should always use CSSStyleCopyNext() and CSSStyleSetNext() to access it.

 @see CSSSheet.h
 @see CSSProperties.h

 */

#include <DocFormats/DFXMLForward.h>
#include "CSSSelector.h"
#include "CSSProperties.h"
#include "DFCallback.h"
#include "DFTypes.h"

////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                //
//                                            CSSStyle                                            //
//                                                                                                //
////////////////////////////////////////////////////////////////////////////////////////////////////

#define DFTableSuffixWholeTable ""
#define DFTableSuffixCell " > * > tr > td"
#define DFTableSuffixFirstRow " > * > tr:first-of-type > td"
#define DFTableSuffixLastRow " > * > tr:last-of-type > td"
#define DFTableSuffixFirstCol " > * > tr > td:first-of-type"
#define DFTableSuffixLastCol " > * > tr > td:last-of-type"
#define DFTableSuffixBand1Vert " > * > tr:nth-of-type(odd) > td"
#define DFTableSuffixBand2Vert " > * > tr:nth-of-type(even) > td"
#define DFTableSuffixBand1Horz " > * > tr > td:nth-of-type(odd)"
#define DFTableSuffixBand2Horz " > * > tr > td:nth-of-type(even)"
#define DFTableSuffixNWCell " > * > tr:first-of-type > td:first-of-type"
#define DFTableSuffixNECell " > * > tr:first-of-type > td:last-of-type"
#define DFTableSuffixSWCell " > * > tr:last-of-type > td:first-of-type"
#define DFTableSuffixSECell " > * > tr:last-of-type > td:last-of-type"

typedef struct CSSStyle CSSStyle;

struct CSSStyle {
    size_t retainCount;

    char *selector;
    char *elementName;
    char *className;
    Tag tag;
    int headingLevel; // 0 for all non-heading styles, 1-6 otherwise
    StyleFamily family;

    struct DFHashTable *rules;
    DFCallback *changeCallbacks;
    int latent;
    int dirty;
};

/**
 Create a new CSSStyle object, with the specified identifier. In addition to initialising the
`selector` field, this also sets the `elementName`, `className`, `tag`, `headingLevel`, and `family`
 fields based on the content of the selector.

 When working with stylesheets, you should never call this function yourself. Instead, call
 CSSSheetLookupSelector() with the `add` parameter set to 1. This way, if a style already exists
 in the stylesheet with the same name, you will not end up with a duplicate.
 */
CSSStyle *CSSStyleNew(const char *ident);
CSSStyle *CSSStyleRetain(CSSStyle *style);
void CSSStyleRelease(CSSStyle *style);

/**
 Change the selector associated with the style. Like CSSStyleNew(), this also sets the
 `elementName`, `className`, `tag`, `headingLevel`, and `family` fields appropriately.

 To maintain consistency with the hash table maintained by CSSStyle, you should remove the style
 from the stylesheet before changing the selector, and add it back again afterwards. This way, it
 will maintain the correct mapping from selectors to styles, so that subsequent calls to
 CSSSheetLookupSelector() with the new selector will work correctly --- i.e. by returning this
 object. Note that when removing the style from the stylesheet, the reference count will be
 decremented, so you should temporarily grab an additional reference to this object using
 CSSStyleRetain() and later release it with CSSStyleRelease(). See replaceSelectorsInSheet() for an
 example of where this is done.
 */
void CSSStyleSetSelector(CSSStyle *style, const char *selector);

char *CSSStyleCopyDisplayName(CSSStyle *style);
void CSSStyleSetDisplayName(CSSStyle *style, const char *newDisplayName);
char *CSSStyleCopyParent(CSSStyle *style);
void CSSStyleSetParent(CSSStyle *style, const char *newParent);
char *CSSStyleCopyNext(CSSStyle *style);
void CSSStyleSetNext(CSSStyle *style, const char *newNext);
int CSSStyleIsCustom(CSSStyle *style);

/**
 Get the default rule (the one with an empty prefix) for this style
 */
CSSProperties *CSSStyleRule(CSSStyle *style);
int CSSStyleIsEmpty(CSSStyle *style);

/**
 Get the rule whose properties apply to cells within a table, assuming this style is a table style.
 This is equivalent to calling CSSStyleRuleForSuffix() with a parameter of `" > * > tr > td"`.
 */
CSSProperties *CSSStyleCell(CSSStyle *style);

/**
 Get the rule whose properties define content and its appearance that should appear before elements
 associated with this style. This is equivalent to calling CSSStyleRuleForSuffix() with a parameter
 of `"::before"`.
 */
CSSProperties *CSSStyleBefore(CSSStyle *style);

/**
 Retrieve a NULL-terminated array of suffixes corresponding to the rules in this style. This array
 can still be used after changes to the style object, as contains its own copy of the suffixes.

 The returned array is newly-allocated, and must be freed by the caller. The strings are allocated
 in the same block of memory as the array itself, so a single call to `free` is sufficient.

 @see DFHashTableCopyKeys()
 */
const char **CSSStyleCopySuffixes(CSSStyle *style);

/**
 Get the rule associated with this style that has the specified suffix. The `suffix` parameter must
 be non-NULL, but you can pass the empty string to retrive the default rule.

 @see CSSStyleRule()
 @see CSSStyleCell()
 @see CSSStyleBefore()
 */
CSSProperties *CSSStyleRuleForSuffix(CSSStyle *style, const char *suffix);

/**
 Get the rule associated with a particular aspect of table formatting, such as the first row or
 column. The `tableComponent` parameter should be one of the macros defined near the top of this
 file, such as `DFTableSuffixFirstRow`.
 */
CSSProperties *CSSStyleRuleForTableComponent(CSSStyle *style, const char *tableComponent);

/**
 Set the default properties that are used by typical web browser for this style. With a regular HTML
 file, if you specify e.g. a `h1` element, the browser knows to display that in a larger, bold font.
 This is because browsers have internal defaults for certain built-in elements. However, when
 converting to other file formats such as docx and ODF, these built-in defaults are not present, so
 we need to make the properties explicit.

 The purpose of this function is to set those properties, so that a document converted from HTML to
 another format will have the defaults set explicitly. It should be called when you are adding a new
 style to an non-HTML document, and you want to make sure the apperance matches that of the HTML
 file as displayed by a browser.
 */
void CSSStyleAddDefaultHTMLProperties(CSSStyle *style);

void CSSStylePrint(CSSStyle *style, const char *indent);
