/** \file lowlevel_index.cpp .
-----------------------------------------------------------------------------


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

-----------------------------------------------------------------------------

   Description:

-----------------------------------------------------------------------------


-------------------------------------------------------------------------- */


/* ----------------------------------------------------------------------- */
/*       Include dependencies                                              */
/* ----------------------------------------------------------------------- */
#include "uima/pragmas.hpp"

#include "uima/lowlevel_index.hpp"
#include "uima/lowlevel_fsheap.hpp"
#include "uima/lowlevel_fsfilter.hpp"
#include "uima/lowlevel_indexiterator.hpp"
#include "uima/lowlevel_indexcomparator.hpp"
#include "uima/lowlevel_indexrepository.hpp"
#include "uima/msg.h"

/* ----------------------------------------------------------------------- */
/*       Constants                                                         */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Forward declarations                                              */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Types / Classes                                                   */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Implementation                                                    */
/* ----------------------------------------------------------------------- */

namespace uima {
  namespace lowlevel {

    IndexABase::IndexABase(IndexRepository const & crIndexRepository,
                           uima::lowlevel::TyFSType tyType)
        : iv_crIndexRepository(crIndexRepository),
        iv_crFSHeap(iv_crIndexRepository.getFSHeap() ),
        iv_crTypeSystem(iv_crFSHeap.getTypeSystem()),
        iv_tyFSType(tyType) {
      assert( iv_crTypeSystem.isValidType(iv_tyFSType) );
    }


    /**
     * generic implementation of find().
     */
    TyFS IndexABase::find(TyFS fs) const {
      auto_ptr<IndexIterator> it(createIterator());
      assert( EXISTS(it.get()) );
      for (it->moveToFirst(); it->isValid(); it->moveToNext() ) {
        TyFS nextFS = it->get();
        if (nextFS == fs) {
          return fs;
        }
      }
      return uima::lowlevel::FSHeap::INVALID_FS;
    }


    /**
     * An iterator on top of another (decorator) which does simple filtering.
     */
    class FilterIndexIterator : public IndexIterator {
    private:
      FSFilter const * iv_cpFilter;
      IndexIterator* iv_pIterator;

      void moveToNextUnfiltered() {
        while (iv_pIterator->isValid()) {
          bool bIsFiltered = iv_cpFilter->isFiltered(iv_pIterator->get());
          if (!bIsFiltered) {
            return;
          } else {
            iv_pIterator->moveToNext();
          }
        }
      }

      void moveToPreviousUnfiltered() {
        while (iv_pIterator->isValid()) {
          bool bIsFiltered = iv_cpFilter->isFiltered(iv_pIterator->get());
          if (!bIsFiltered) {
            return;
          } else {
            iv_pIterator->moveToPrevious();
          }
        }
      }

    public:
      FilterIndexIterator(FSFilter const * cpFilter, IndexIterator* pIterator)
          : iv_cpFilter(cpFilter),
          iv_pIterator(pIterator) {}

      virtual ~FilterIndexIterator() {
        assert( EXISTS(iv_pIterator) );
        delete iv_pIterator;
      }

      void moveToFirst() {
        assert( EXISTS(iv_pIterator) );
        iv_pIterator->moveToFirst();
        moveToNextUnfiltered();
      }

      void moveToLast() {
        assert( EXISTS(iv_pIterator) );
        iv_pIterator->moveToLast();
        moveToPreviousUnfiltered();
      }

      void moveToPrevious() {
        assert(isValid());
        iv_pIterator->moveToPrevious();
        moveToPreviousUnfiltered();
      }

      void moveToNext() {
        assert(isValid());
        iv_pIterator->moveToNext();
        moveToNextUnfiltered();
      }

      TyFS get() const {
          assert(isValid());
          return iv_pIterator->get();
        }

      TyFSType getTyFSType() const {
        assert( isValid() );
        return iv_pIterator->getTyFSType();
      }

      bool isValid() const {
        assert( EXISTS(iv_pIterator) );
        return iv_pIterator->isValid();
      }

      IndexIterator* clone() const {
        return new FilterIndexIterator(iv_cpFilter, iv_pIterator->clone());
      }

      bool moveTo(TyFS fs) {
        assert( EXISTS(iv_pIterator) );
        return iv_pIterator->moveTo(fs);
      }

    };


    IndexIterator* IndexABase::createFilteredIterator(FSFilter const * cpFilter) const {
      IndexIterator* pit = createIterator();
      assert( EXISTS(pit) );
      IndexIterator* result = new FilterIndexIterator(cpFilter, pit);
      assert( EXISTS(result) );
      return result;
    }

  }
}



/* ----------------------------------------------------------------------- */



