/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

/*
  text.cpp
*/

#include "text.h"

#include <QtCore/qregexp.h>

#include <stdio.h>

QT_BEGIN_NAMESPACE

Text::Text() : first(nullptr), last(nullptr) {}

Text::Text(const QString &str) : first(nullptr), last(nullptr)
{
    operator<<(str);
}

Text::Text(const Text &text) : first(nullptr), last(nullptr)
{
    operator=(text);
}

Text::~Text()
{
    clear();
}

Text &Text::operator=(const Text &text)
{
    if (this != &text) {
        clear();
        operator<<(text);
    }
    return *this;
}

Text &Text::operator<<(Atom::AtomType atomType)
{
    return operator<<(Atom(atomType));
}

Text &Text::operator<<(const QString &string)
{
    return operator<<(Atom(Atom::String, string));
}

Text &Text::operator<<(const Atom &atom)
{
    if (atom.count() < 2) {
        if (first == nullptr) {
            first = new Atom(atom.type(), atom.string());
            last = first;
        } else
            last = new Atom(last, atom.type(), atom.string());
    } else {
        if (first == nullptr) {
            first = new Atom(atom.type(), atom.string(), atom.string(1));
            last = first;
        } else
            last = new Atom(last, atom.type(), atom.string(), atom.string(1));
    }
    return *this;
}

/*!
  Special output operator for LinkAtom. It makes a copy of
  the LinkAtom \a atom and connects the cop;y to the list
  in this Text.
 */
Text &Text::operator<<(const LinkAtom &atom)
{
    if (first == nullptr) {
        first = new LinkAtom(atom);
        last = first;
    } else
        last = new LinkAtom(last, atom);
    return *this;
}

Text &Text::operator<<(const Text &text)
{
    const Atom *atom = text.firstAtom();
    while (atom != nullptr) {
        operator<<(*atom);
        atom = atom->next();
    }
    return *this;
}

void Text::stripFirstAtom()
{
    if (first != nullptr) {
        if (first == last)
            last = nullptr;
        Atom *oldFirst = first;
        first = first->next();
        delete oldFirst;
    }
}

void Text::stripLastAtom()
{
    if (last != nullptr) {
        Atom *oldLast = last;
        if (first == last) {
            first = nullptr;
            last = nullptr;
        } else {
            last = first;
            while (last->next() != oldLast)
                last = last->next();
            last->setNext(nullptr);
        }
        delete oldLast;
    }
}

/*!
  This function traverses the atom list of the Text object,
  extracting all the string parts. It concatenates them to
  a result string and returns it.
 */
QString Text::toString() const
{
    QString str;
    const Atom *atom = firstAtom();
    while (atom != nullptr) {
        if (atom->type() == Atom::String || atom->type() == Atom::AutoLink
            || atom->type() == Atom::C)
            str += atom->string();
        atom = atom->next();
    }
    return str;
}

/*!
  Returns true if this Text contains the substring \a str.
 */
bool Text::contains(const QString &str) const
{
    const Atom *atom = firstAtom();
    while (atom != nullptr) {
        if (atom->type() == Atom::String || atom->type() == Atom::AutoLink
            || atom->type() == Atom::C)
            if (atom->string().contains(str, Qt::CaseInsensitive))
                return true;
        atom = atom->next();
    }
    return false;
}

Text Text::subText(Atom::AtomType left, Atom::AtomType right, const Atom *from,
                   bool inclusive) const
{
    const Atom *begin = from ? from : firstAtom();
    const Atom *end;

    while (begin != nullptr && begin->type() != left)
        begin = begin->next();
    if (begin != nullptr) {
        if (!inclusive)
            begin = begin->next();
    }

    end = begin;
    while (end != nullptr && end->type() != right)
        end = end->next();
    if (end == nullptr)
        begin = nullptr;
    else if (inclusive)
        end = end->next();
    return subText(begin, end);
}

Text Text::sectionHeading(const Atom *sectionLeft)
{
    if (sectionLeft != nullptr) {
        const Atom *begin = sectionLeft;
        while (begin != nullptr && begin->type() != Atom::SectionHeadingLeft)
            begin = begin->next();
        if (begin != nullptr)
            begin = begin->next();

        const Atom *end = begin;
        while (end != nullptr && end->type() != Atom::SectionHeadingRight)
            end = end->next();

        if (end != nullptr)
            return subText(begin, end);
    }
    return Text();
}

const Atom *Text::sectionHeadingAtom(const Atom *sectionLeft)
{
    if (sectionLeft != nullptr) {
        const Atom *begin = sectionLeft;
        while (begin != nullptr && begin->type() != Atom::SectionHeadingLeft)
            begin = begin->next();
        if (begin != nullptr)
            begin = begin->next();

        return begin;
    }
    return nullptr;
}

void Text::dump() const
{
    const Atom *atom = firstAtom();
    while (atom != nullptr) {
        QString str = atom->string();
        str.replace("\\", "\\\\");
        str.replace("\"", "\\\"");
        str.replace("\n", "\\n");
        str.replace(QRegExp("[^\x20-\x7e]"), "?");
        if (!str.isEmpty())
            str = " \"" + str + QLatin1Char('"');
        fprintf(stderr, "    %-15s%s\n", atom->typeString().toLatin1().data(),
                str.toLatin1().data());
        atom = atom->next();
    }
}

Text Text::subText(const Atom *begin, const Atom *end)
{
    Text text;
    if (begin != nullptr) {
        while (begin != end) {
            text << *begin;
            begin = begin->next();
        }
    }
    return text;
}

void Text::clear()
{
    while (first != nullptr) {
        Atom *atom = first;
        first = first->next();
        delete atom;
    }
    first = nullptr;
    last = nullptr;
}

int Text::compare(const Text &text1, const Text &text2)
{
    if (text1.isEmpty())
        return text2.isEmpty() ? 0 : -1;
    if (text2.isEmpty())
        return 1;

    const Atom *atom1 = text1.firstAtom();
    const Atom *atom2 = text2.firstAtom();

    for (;;) {
        if (atom1->type() != atom2->type())
            return (int)atom1->type() - (int)atom2->type();
        int cmp = QString::compare(atom1->string(), atom2->string());
        if (cmp != 0)
            return cmp;

        if (atom1 == text1.lastAtom())
            return atom2 == text2.lastAtom() ? 0 : -1;
        if (atom2 == text2.lastAtom())
            return 1;
        atom1 = atom1->next();
        atom2 = atom2->next();
    }
}

QT_END_NAMESPACE
