/*
**********************************************************************
*   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;
}



