/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

/*
  text.cpp
*/

#include <qregexp.h>
#include "text.h"
#include <stdio.h>

QT_BEGIN_NAMESPACE

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

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

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

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

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

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

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

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

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

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

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

QString Text::toString() const
{
    QString str;
    const Atom* atom = firstAtom();
    while (atom != 0) {
	if (atom->type() == Atom::String ||
             atom->type() == Atom::AutoLink ||
             atom->type() == Atom::GuidLink)
	    str += atom->string();
	atom = atom->next();
    }
    return str;
}

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

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

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

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

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

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

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

	return begin;
    }
    return 0;
}

void Text::dump() const
{
    const Atom* atom = firstAtom();
    while (atom != 0) {
	QString str = atom->string();
	str.replace("\\", "\\\\");
	str.replace("\"", "\\\"");
	str.replace("\n", "\\n");
	str.replace(QRegExp("[^\x20-\x7e]"), "?");
	if (!str.isEmpty())
	    str = " \"" + str + "\"";
	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 != 0) {
	while (begin != end) {
	    text << *begin;
	    begin = begin->next();
	}
    }
    return text;
}

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

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
