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

#include "CSSStyle.h"
#include "CSSSheet.h"
#include "CSS.h"
#include "CSSProperties.h"
#include "CSSSelector.h"
#include "DFHTML.h"
#include "DFHashTable.h"
#include "DFString.h"
#include "DFCommon.h"
#include "DFPlatform.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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

// FIXME: The dirty property is supposed to be set whenever any aspect if this style changes,
// including any property of one of its rules, and the addition or removal of rules.

// I'm not sure if this is actually relevant in the context of the new model under which we set
// the stylesheet as a whole, because the in the old model styles were updated individually
// (which caused serialization of the entire stylesheet anyway, just in javascript).

static void ruleChanged(void *ctx, void *object, void *data)
{
    CSSStyle *style = (CSSStyle *)ctx;
    CSSProperties *properties = (CSSProperties *)object;
    if (properties->dirty) {
        properties->dirty = 0;
        if (!style->dirty) { // Minimise callback invocations
            style->dirty = 1;
            DFCallbackInvoke(style->changeCallbacks,style,NULL);
        }
    }
}

CSSStyle *CSSStyleNew(const char *selector)
{
    CSSStyle *style = (CSSStyle *)xcalloc(1,sizeof(CSSStyle));
    style->retainCount = 1;
    CSSStyleSetSelector(style,selector);
    style->rules = DFHashTableNew((DFCopyFunction)CSSPropertiesRetain,(DFFreeFunction)CSSPropertiesRelease);
    CSSStyleRuleForSuffix(style,""); // Create the base rule
    return style;
}

CSSStyle *CSSStyleRetain(CSSStyle *style)
{
    if (style != NULL)
        style->retainCount++;

    return style;
}

void CSSStyleRelease(CSSStyle *style)
{
    if ((style == NULL) || (--style->retainCount > 0))
        return;

    free(style->selector);
    free(style->elementName);
    free(style->className);
    const char **keys = DFHashTableCopyKeys(style->rules);
    for (int i = 0; keys[i]; i++) {
        CSSProperties *rule = DFHashTableLookup(style->rules,keys[i]);
        DFCallbackRemove(&rule->changeCallbacks,ruleChanged,style);
    }
    free(keys);
    DFHashTableRelease(style->rules);
    assert(style->changeCallbacks == NULL);
    free(style);
}

void CSSStyleSetSelector(CSSStyle *style, const char *newSelector)
{
    // Take a copy of newSelector first, just in case it's one of the values we're about to free
    char *selector = xstrdup(newSelector);

    free(style->selector);
    free(style->elementName);
    free(style->className);

    style->selector = selector;
    style->elementName = CSSSelectorCopyElementName(style->selector);
    style->className = CSSSelectorCopyClassName(style->selector);
    style->tag = CSSSelectorGetTag(style->selector);
    style->headingLevel = CSSSelectorHeadingLevel(style->selector);
    style->family = CSSSelectorFamily(style->selector);
}

int CSSStyleIsCustom(CSSStyle *style)
{
    if (CSSGetDefault(CSSStyleRule(style)))
        return 0;
    if (CSSIsBuiltinSelector(style->selector))
        return 0;
    return 1;
}

char *CSSStyleCopyParent(CSSStyle *style)
{
    const char *quotedValue = CSSGet(CSSStyleRule(style),"-uxwrite-parent");
    return DFUnquote(quotedValue);
}

void CSSStyleSetParent(CSSStyle *style, const char *newParent)
{
    char *quotedParent = DFQuote(newParent);
    CSSPut(CSSStyleRule(style),"-uxwrite-parent",quotedParent);
    free(quotedParent);
}

char *CSSStyleCopyNext(CSSStyle *style)
{
    const char *quotedValue = CSSGet(CSSStyleRule(style),"-uxwrite-next");
    return DFUnquote(quotedValue);
}

void CSSStyleSetNext(CSSStyle *style, const char *newNext)
{
    char *quotedNext = DFQuote(newNext);
    CSSPut(CSSStyleRule(style),"-uxwrite-next",quotedNext);
    free(quotedNext);
}

char *CSSStyleCopyDisplayName(CSSStyle *style)
{
    const char *quotedValue = CSSGet(CSSStyleRule(style),"-uxwrite-display-name");
    return DFUnquote(quotedValue);
}

void CSSStyleSetDisplayName(CSSStyle *style, const char *newDisplayName)
{
    char *quotedDisplayName = DFQuote(newDisplayName);
    CSSPut(CSSStyleRule(style),"-uxwrite-display-name",quotedDisplayName);
    free(quotedDisplayName);
}

const char **CSSStyleCopySuffixes(CSSStyle *style)
{
    return DFHashTableCopyKeys(style->rules);
}

CSSProperties *CSSStyleRuleForSuffix(CSSStyle *style, const char *suffix)
{
    if (style == NULL)
        return NULL;;

    CSSProperties *result = DFHashTableLookup(style->rules,suffix);
    if (result == NULL) {
        result = CSSPropertiesNew();
        DFHashTableAdd(style->rules,suffix,result);
        DFCallbackAdd(&result->changeCallbacks,ruleChanged,style);
        CSSPropertiesRelease(result);
    }
    return result;
}

static const char *suffixForTableComponent(const char *tableComponent)
{
    if (tableComponent == NULL)
        return NULL;
    else if (!strcmp(tableComponent,"wholeTable"))
        return DFTableSuffixWholeTable;
    else if (!strcmp(tableComponent,"cell"))
        return DFTableSuffixCell;
    else if (!strcmp(tableComponent,"firstRow"))
        return DFTableSuffixFirstRow;
    else if (!strcmp(tableComponent,"lastRow"))
        return DFTableSuffixLastRow;
    else if (!strcmp(tableComponent,"firstCol"))
        return DFTableSuffixFirstCol;
    else if (!strcmp(tableComponent,"lastCol"))
        return DFTableSuffixLastCol;
    else if (!strcmp(tableComponent,"band1Vert"))
        return DFTableSuffixBand1Vert;
    else if (!strcmp(tableComponent,"band2Vert"))
        return DFTableSuffixBand2Vert;
    else if (!strcmp(tableComponent,"band1Horz"))
        return DFTableSuffixBand1Horz;
    else if (!strcmp(tableComponent,"band2Horz"))
        return DFTableSuffixBand2Horz;
    else if (!strcmp(tableComponent,"nwCell"))
        return DFTableSuffixNWCell;
    else if (!strcmp(tableComponent,"neCell"))
        return DFTableSuffixNECell;
    else if (!strcmp(tableComponent,"swCell"))
        return DFTableSuffixSWCell;
    else if (!strcmp(tableComponent,"seCell"))
        return DFTableSuffixSECell;
    else
        return NULL;
}

CSSProperties *CSSStyleRuleForTableComponent(CSSStyle *style, const char *tableComponent)
{
    const char *suffix = suffixForTableComponent(tableComponent);
    if (suffix == NULL)
        return NULL;
    return CSSStyleRuleForSuffix(style,suffix);
}

CSSProperties *CSSStyleRule(CSSStyle *style)
{
    return CSSStyleRuleForSuffix(style,"");
}

int CSSStyleIsEmpty(CSSStyle *style)
{
    const char **allSuffixes = CSSStyleCopySuffixes(style);
    for (int i = 0; allSuffixes[i]; i++) {
        const char *suffix = allSuffixes[i];
        CSSProperties *properties = CSSStyleRuleForSuffix(style,suffix);
        if (DFHashTableCount(properties->hashTable) > 0) {
            free(allSuffixes);
            return 0;
        }
    }
    free(allSuffixes);
    return 1;
}

CSSProperties *CSSStyleCell(CSSStyle *style)
{
    return CSSStyleRuleForSuffix(style,DFTableSuffixCell);
}

CSSProperties *CSSStyleBefore(CSSStyle *style)
{
    return CSSStyleRuleForSuffix(style,"::before");
}

void CSSStyleAddDefaultHTMLProperties(CSSStyle *style)
{
    // FIXME: Not covered by tests
    char *elementName = CSSSelectorCopyElementName(style->selector);
    char *className = CSSSelectorCopyClassName(style->selector);
    if ((className == NULL) && (strlen(elementName) == 2) && (elementName[0] == 'h')) {
        CSSProperties *rule = CSSStyleRule(style);
        if (!strcmp(elementName,"h1")) {
            if (CSSGet(rule,"font-weight") == NULL)
                CSSPut(rule,"font-weight","bold");
            if (CSSGet(rule,"font-size") == NULL)
                CSSPut(rule,"font-size","24pt");
        }
        else if (!strcmp(elementName,"h2")) {
            if (CSSGet(rule,"font-weight") == NULL)
                CSSPut(rule,"font-weight","bold");
            if (CSSGet(rule,"font-size") == NULL)
                CSSPut(rule,"font-size","18pt");
        }
        else if (!strcmp(elementName,"h3")) {
            if (CSSGet(rule,"font-weight") == NULL)
                CSSPut(rule,"font-weight","bold");
            if (CSSGet(rule,"font-size") == NULL)
                CSSPut(rule,"font-size","14pt");
        }
        else if (!strcmp(elementName,"h4")) {
            if (CSSGet(rule,"font-weight") == NULL)
                CSSPut(rule,"font-weight","bold");
            if (CSSGet(rule,"font-size") == NULL)
                CSSPut(rule,"font-size","12pt");
        }
        else if (!strcmp(elementName,"h5")) {
            if (CSSGet(rule,"font-weight") == NULL)
                CSSPut(rule,"font-weight","bold");
            if (CSSGet(rule,"font-size") == NULL)
                CSSPut(rule,"font-size","10pt");
        }
        else if (!strcmp(elementName,"h6")) {
            if (CSSGet(rule,"font-weight") == NULL)
                CSSPut(rule,"font-weight","bold");
            if (CSSGet(rule,"font-size") == NULL)
                CSSPut(rule,"font-size","8pt");
        }
    }
    free(elementName);
    free(className);
}

void CSSStylePrint(CSSStyle *style, const char *indent)
{
    char *propertiesIndent = DFFormatString("%s    ",indent);

    const char **allSuffixes = CSSStyleCopySuffixes(style);
    DFSortStringsCaseInsensitive(allSuffixes);
    for (int suffixIndex = 0; allSuffixes[suffixIndex]; suffixIndex++) {
        const char *suffix = allSuffixes[suffixIndex];
        char *quotedSuffix = DFQuote(suffix);
        printf("%ssuffix %s\n",indent,quotedSuffix);
        free(quotedSuffix);
        CSSProperties *properties = CSSStyleRuleForSuffix(style,suffix);
        CSSPropertiesPrint(properties,propertiesIndent);
    }
    free(allSuffixes);

    free(propertiesIndent);
}
