/*
**********************************************************************
*   Copyright (C) 1999-2000 IBM and others. All rights reserved.
**********************************************************************
*   Date        Name        Description
*  03/22/2000   helena      Creation.
**********************************************************************
*/

#include "unicode/brkiter.h"
#include "unicode/schriter.h"
#include "srchiter.h"

int32_t const SearchIterator::DONE = -1;
int32_t const SearchIterator::BEFORE = -2;    

SearchIterator::SearchIterator(void) :
    index(0),
    length(0),
    target(0),
    backward(FALSE), /* going forward */
    breaker(NULL),
    overlap(TRUE)
{
    UErrorCode status = U_ZERO_ERROR;
    this->breaker = BreakIterator::createCharacterInstance(Locale::getDefault(), status);
    if (U_FAILURE(status)) return;
}

SearchIterator::SearchIterator(CharacterIterator* target, 
                               BreakIterator* breaker) :
    index(0),
    length(0),
    target(0),
    backward(FALSE), /* going forward */
    breaker(NULL),
    overlap(TRUE)
{
    this->target = target;
    
    this->breaker = breaker;
    this->breaker->adoptText(this->target);
    
    index = this->target->startIndex();
    length = 0;
}

SearchIterator::SearchIterator(const  SearchIterator&   other) :
    length(other.length),
    target(0),
    backward(other.backward), /* going forward */
    breaker(NULL),
    overlap(other.overlap)  
{
    index = other.target->startIndex();
    this->target = other.target->clone();
    
    this->breaker = ((BreakIterator&)other.breaker).clone();
    this->breaker->adoptText(this->target);
}

SearchIterator::~SearchIterator()
{
    // deletion of breaker will delete target
    if (breaker != NULL) {
        delete breaker;
        breaker = 0;
    }
}

UBool SearchIterator::operator == (const SearchIterator& that) const
{
    if (this == &that) return TRUE;
    if (*that.breaker != *breaker) return FALSE;
    else if (*that.target != *target) return FALSE;
    else if (that.backward != backward) return FALSE;
    else if (that.index != index) return FALSE;
    else if (that.length != length) return FALSE;
    else if (that.overlap != overlap) return FALSE;
    else return TRUE;
}

int32_t SearchIterator::first(void) 
{
    setIndex(SearchIterator::BEFORE);
    return next();
}

int32_t SearchIterator::following(int32_t pos) 
{
    setIndex(pos);
    return next();
}
    
int32_t SearchIterator::last(void) 
{
    setIndex(SearchIterator::DONE);
    return previous();
}

int32_t SearchIterator::preceding(int32_t pos) 
{
    setIndex(pos);
    return previous();
}
    
int32_t SearchIterator::next(void) 
{
    if (index == SearchIterator::BEFORE){
        // Starting at the beginning of the text
        index = target->startIndex();
    } else if (index == SearchIterator::DONE) {
        return SearchIterator::DONE;
    } else if (length > 0) {
        // Finding the next match after a previous one
        index += overlap ? 1 : length;
    }
    index -= 1;
    backward = FALSE;
        
    do {
        UErrorCode status = U_ZERO_ERROR;
        length = 0;
        index = handleNext(index + 1, status);
        if (U_FAILURE(status))
        {
            return SearchIterator::DONE;
        }
    } while (index != SearchIterator::DONE && !isBreakUnit(index, index+length));
    
    return index;
}

int32_t SearchIterator::previous(void) 
{
    if (index == SearchIterator::DONE) {
        index = target->endIndex();
    } else if (index == SearchIterator::BEFORE) {
        return SearchIterator::DONE;
    } else if (length > 0) {
        // Finding the previous match before a following one
        index = overlap ? index + length - 1 : index;
    }
    index += 1;
    backward = TRUE;
    
    do {
        UErrorCode status = U_ZERO_ERROR;
        length = 0;
        index = handlePrev(index - 1, status);
        if (U_FAILURE(status))
        {
            return SearchIterator::DONE;
        }
    } while (index != SearchIterator::DONE && !isBreakUnit(index, index+length));

    if (index == SearchIterator::DONE) {
        index = SearchIterator::BEFORE;
    }
    return getIndex();
}


int32_t SearchIterator::getIndex() const
{
    return index == SearchIterator::BEFORE ? SearchIterator::DONE : index;
}

void SearchIterator::setOverlapping(UBool allowOverlap) 
{
     overlap = allowOverlap;
}
    
UBool SearchIterator::isOverlapping(void) const
{
    return overlap;
}
    
int32_t SearchIterator::getMatchLength(void) const
{
    return length;
}

void SearchIterator::reset(void)
{
    length = 0;
    if (backward == FALSE) {
        index = 0;
        target->setToStart();
        breaker->first();
    } else {
        index = SearchIterator::DONE;
        target->setToEnd();
        breaker->last();
    }
    overlap = TRUE;
}

void SearchIterator::setBreakIterator(const BreakIterator* iterator) 
{
    CharacterIterator *buffer = target->clone();
    delete breaker;
    breaker = iterator->clone();
    breaker->adoptText(buffer);
}

const BreakIterator& SearchIterator::getBreakIterator(void) const
{
    return *breaker;
}
 
void SearchIterator::setTarget(const UnicodeString& newText)
{
    if (target != NULL && target->getDynamicClassID()
            == StringCharacterIterator::getStaticClassID()) {
        ((StringCharacterIterator*)target)->setText(newText);
    }
    else {
        delete target;
		target = new StringCharacterIterator(newText);
        target->first();
        breaker->adoptText(target);
    }
}
  
void SearchIterator::adoptTarget(CharacterIterator* iterator) {
    target = iterator;
    breaker->adoptText(target);
    setIndex(SearchIterator::BEFORE);
}

const CharacterIterator& SearchIterator::getTarget(void) const
{
    SearchIterator* nonConstThis = (SearchIterator*)this;
    
    // The iterator is initialized pointing to no text at all, so if this
    // function is called while we're in that state, we have to fudge an
    // an iterator to return.
    if (nonConstThis->target == NULL)
        nonConstThis->target = new StringCharacterIterator("");
    return *nonConstThis->target;
}

void SearchIterator::getMatchedText(UnicodeString& result) 
{
    result.remove();
    if (length > 0) {
        int i = 0;
        for (UChar c = target->setIndex(index); i < length; c = target->next(), i++)
        {
            result += c;
        }
    }
}


void SearchIterator::setMatchLength(int32_t length) 
{
    this->length = length;
}

void SearchIterator::setIndex(int32_t pos) {
    index = pos;
    length = 0;
}

UBool SearchIterator::isBreakUnit(int32_t start, 
                                   int32_t end)
{
    if (breaker == NULL) {
        return TRUE;
    } 
    UBool startBound = breaker->isBoundary(start);
    UBool endBound = (end == target->endIndex()) || breaker->isBoundary(end);
    
    return startBound && endBound;
}



