// 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

 A CSSSheet object represents a CSS stylesheet. It contains a series of styles, identified by
 their selector (element and optional class name), each of which is corresponds to a CSSStyle
 object.

 CSSSheet uses reference counting. When you create a new object using CSSSheetNew, it initially
 has a reference count of 1. You can increment and decrement the reference count by calling
 CSSSheetRetain and CSSSheetRelease, respectively. When the reference count drops to 0, the object
 will be freed from memory.

 Each style is identified by its **base selector**, or simply **selector** for short. This
 corresponds to the initial part of the selector used in all rules of a CSS stylesheet that are
 associated with that style. The selector consists of an element name (e.g. `h1`), plus an optional
 class name (e.g. `h1.class`).

 To add a new style or retrieve an existing style from the stylesheet, use @ref
 CSSSheetLookupSelector or @ref CSSSheetLookupElement. Both of these functions take an `add`
 parameter, which indicate whether the style should be added if it does not already exist. If you
 just want to get an existing file, pass in zero for the add parameter. If you want to add the style
 if it does not already exist, pass in a non-zero value. @ref CSSSheetLookupSelector takes a
 selector (element name and optional class name combined into a single string) as a parameter; @ref
 CSSSheetLookupElement takes the element name and class name as separate parameters.

 @see CSSStyle.h
 @see CSSProperties.h

 */

#include "CSSStyle.h"
#include "DFHashTable.h"

////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                //
//                                            CSSSheet                                            //
//                                                                                                //
////////////////////////////////////////////////////////////////////////////////////////////////////

typedef struct CSSSheet CSSSheet;

CSSSheet *CSSSheetNew(void);
CSSSheet *CSSSheetRetain(CSSSheet *sheet);
void CSSSheetRelease(CSSSheet *sheet);

CSSProperties *CSSSheetPageProperties(CSSSheet *sheet);
CSSProperties *CSSSheetBodyProperties(CSSSheet *sheet);
int CSSSheetHeadingNumbering(CSSSheet *sheet);
void CSSSheetSetHeadingNumbering(CSSSheet *sheet, int enabled);
int CSSSheetIsNumberingUsed(CSSSheet *sheet);

/**
 Retrieve a NULL-terminated array containing the base selectors of styles in this stylesheet. A
 base selector consists of an element name and optional class name (e.g. `h1` or `h1.Appendix`),
 and is used to uniquely identify a style. You can pass these selectors to CSSSheetLookupSelector()
 to get the actual style objects.

 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 **CSSSheetCopySelectors(CSSSheet *sheet);

/**
 Add a new style to the stylesheet, replacing any existing style with the same name, if present.

 Generally, you should not call this function directly, but instead use CSSSheetLookupSelector()
 with an `add` parameter of 1, so that if there's already a style with the same selector, it will
 remain.
 */
void CSSSheetAddStyle(CSSSheet *sheet, CSSStyle *style);

/**
 Remove a style from the stylesheet.

 Note that this causes the CSSSheet object to release its reference to the style, so if you want to
 ensure the CSSStyle object remains in memory after this function is called, you must retain your
 own reference to it. See replaceSelectorsInSheet() for an example.
 */
void CSSSheetRemoveStyle(CSSSheet *sheet, CSSStyle *style);

/**
 Retrieve the CSSStyle object associated with the specified selector, optionally adding it if it
 does not yet exist.

 @param add If non-zero, the style will be added if it does not already exist. If zero, NULL will
 be returned if the style does not exist.
 @param latent If non-zero, and a new style is added, it will be marked as latent. This result in it
 not appearing in the textual representation of a stylesheet. Normally this should be set to zero;
 it is only useful for definining built-in styles in an editing interface which are program defaults
 that are yet to be activated.
 */
CSSStyle *CSSSheetLookupSelector(CSSSheet *sheet, const char *selector, int add, int latent);

/**
 Retrieve the CSSStyle object associated with the specified element name and optional class name,
 optionally adding it if it does not yet exist. The element name *must* be supplied; the class name
 can be NULL. This function behaves in the same way as CSSSheetLookupSelector.

 @param add If non-zero, the style will be added if it does not already exist. If zero, NULL will
 be returned if the style does not exist.
 @param latent If non-zero, and a new style is added, it will be marked as latent. This result in it
 not appearing in the textual representation of a stylesheet. Normally this should be set to zero;
 it is only useful for definining built-in styles in an editing interface which are program defaults
 that are yet to be activated.
 */
CSSStyle *CSSSheetLookupElement(CSSSheet *sheet, const char *elementName, const char *className, int add, int latent);

/**
 Creates a new CSSStyle object whose rules are all "flattened" --- that is, they include all properties
 defined on the style and all of its ancestors.

 Formats like Word and ODF support **style inheritance**, whereby each style can optionally have a
 parent style associated with it. This causes the style to inherit all properties from its parent,
 in the same way that a subclass inherits fields and methods from its superclass in an object-oriented
 programming language. The parent may itself have a parent, and so forth, so there may be any number
 of "ancestors" of the style.

 The process of flattening a style involves starting with a style itself, collecting all properties
 directly defined there, and then repeatedly going through the chain of ancestors adding all properties
 they define as well. The result is that the flattened style contains all inherited properties.

 For example, suppose you had the following three styles defined:

     p.One {
         font-weight: bold;
         font-size: 12pt;
     }

     p.Two {
         -uxwrite-parent: "p.One";
         color: red;
         font-size: 14pt;
     }

     p.Three {
         -uxwrite-parent: "p.Two";
         font-size: 18pt;
         font-style: italic;
     }

 The collapsed style would have the following properties (note that font-size is overridden, so
 we use the definition closest to the original style in preference to the value defined by its
 ancestors):

     p.Three {
         -uxwrite-parent: "p.Two";
         font-weight: bold;        // From p.One
         color: red;               // From p.Two
         font-size: 18pt;          // From p.Three (overriden)
         font-style: italic;       // From p.Three
     }

 The fact that the properties have been flattened like this mean they will display as expected
 in a web browser (and UX Write itself, since it displays documents in the same way as a web
 browser). Without flattening, we would only have the `font-size` and `font-weight` properties
 defined; browsers don't know about the special `-uxwrite-parent` property and cannot infer that
 the style is inherited.

 Unlike all other CSSSheet methods, the CSSStyle object returned by this function is newly
 allocated, and the caller must call CSSStyleRelease on the object when finished with it.
 */
CSSStyle *CSSSheetFlattenedStyle(CSSSheet *sheet, CSSStyle *orig);

/**
 Builds a hash table of rules to be included in the textual representation of the stylesheet. This
 corresponds directly to what is produced by CSSSheetFlattenedStyle(), but is in the form of a hash
 table rather than a string, so that it can be easily manipulated in code.

 Each key in the hash table is a full selector (i.e. base selector + suffix). Each value is another
 hash table, whose keys are property names and whose values are property names.

 The only reason this function is exposed separately from CSSSheetFlattenedStyle() is that UX Write
 needs to pass this information to the javascript portion of the editing code, which uses it for
 things like determining the style to apply to new paragraphs. In general you would normally just
 call CSSSheetFlattenedStyle() instead.

 The returned hash table is newly allocated and must be released by the caller.
 */
DFHashTable *CSSSheetRules(CSSSheet *sheet);

/**
 Converts a stylesheet into its textual representation. All rules are collapsed, all styles are
 flattened, and all CSS declarations which have the same set of proeprties are merged. The result
 can be used as the text content of a HTML `style` element to define the stylesheet for a document,
 or written to an external stylesheet in a `.css` file.

 The string returned by this function is newly-allocated, and must be freed by the caller.
 */
char *CSSSheetCopyCSSText(CSSSheet *sheet);

/**
 Similar to CSSSheetCopyCSSText(), but uses an alternative textual format that lists all rules
 without flattening inherited styles. It is here only for testing purposes; some of the automated
 tests rely on it.

 The string returned by this function is newly-allocated, and must be freed by the caller.
 */
char *CSSSheetCopyText(CSSSheet *sheet);

/**
 Replaces all styles with those defined in the supplied CSS text.

 You can use this function to create a new stylesheet based on the text content of a HTML `style`
 element, or the contents of an external stylesheet in a `.css` file. First call CSSSheetNew, and
 then CSSSheetUpdateFromCSSText with the string representing the CSS text:

     char *cssText = ... // get from HTML <style> element or .css file
     CSSSheet *sheet = CSSSheetNew();
     CSSSheetUpdateFromCSSText(sheet,cssText);

 This function is the inverse of CSSSheetCopyCSSText. If you call CSSSheetCopyCSSText and then
 pass the result to CSSSheetUpdateFromCSSText, you will get the same stylesheet.
 */
void CSSSheetUpdateFromCSSText(CSSSheet *sheet, const char *cssText);

CSSStyle *CSSSheetDefaultStyleForFamily(CSSSheet *sheet, StyleFamily family);
void CSSSheetSetDefaultStyle(CSSSheet *sheet, CSSStyle *style, StyleFamily family);
int CSSStyleIsNumbered(CSSStyle *style);
CSSStyle *CSSSheetGetStyleParent(CSSSheet *sheet, CSSStyle *style);

/**
 Retrieve the parent of a given style, if it has one.

 The CSSStyle object itself records the parent's base selector name in the `-uxwrite-parent`
 property, but in order to actually retrieve that style, it is necessary to have access to the
 CSSSheet object, since this is the only way to get access to the other CSSStyle objects. This
 function checks to see if `-uxwrite-parent` is set, and it so, looks up that selector in the
 stylesheet.

 If the style does not specify a parent, or it does specify a parent but that parent does not exist,
 this function returns NULL.
 */
CSSStyle *CSSSheetParentOfStyle(CSSSheet *sheet, CSSStyle *style);
int CSSIsBuiltinSelector(const char *selector);
