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


#include "uima/api.hpp"
using namespace uima;

class MeetingAnnotator : public Annotator {
private:
  //config param window size
  int mWindowSize;

  //Input types
  Type roomNumberT;
  Type dateT;
  Type timeT;

  //output type and its features
  Type meetingT;
  Feature roomF;
  Feature dateF;
  Feature startTimeF;
  Feature endTimeF;


public:

  MeetingAnnotator(void)
  {
    cout << "MeetingAnnotator: Constructor" << endl;
  }

  ~MeetingAnnotator(void)
  {
    cout << "MeetingAnnotator: Destructor" << endl;
  }

  /** */
  TyErrorId initialize(AnnotatorContext & rclAnnotatorContext)
  {
    cout << "MeetingAnnotator: initialize()" << endl;

    if (!rclAnnotatorContext.isParameterDefined("WindowSize") ||
	rclAnnotatorContext.extractValue("WindowSize", mWindowSize) != UIMA_ERR_NONE) {
      /* log the error condition */
      rclAnnotatorContext.getLogger().logError("Required configuration parameter \"WindowSize\" not found in component descriptor");
      cout << "initialize() - Error. See logfile." << endl;
      return UIMA_ERR_USER_ANNOTATOR_COULD_NOT_INIT;
    }

	if (mWindowSize < 50) {
      rclAnnotatorContext.getLogger().logWarning("WindowSize may be too narrow");
    }

    /* log the configuration parameter setting */
	std::stringstream ss;
	std::string str;
	ss << mWindowSize;
	ss >> str;
    rclAnnotatorContext.getLogger().logMessage("WindowSize = '" + str + "'");

    cout << "initialize() .. mWindowSize.getBuffer: "
	 << mWindowSize << endl;

    return (TyErrorId)UIMA_ERR_NONE;
  }

  /** */
  TyErrorId typeSystemInit(TypeSystem const & crTypeSystem) {
    cout << " typeSystemInit()" << endl;

    //input types
    roomNumberT =  crTypeSystem.getType("org.apache.uima.tutorial.RoomNumber");
    dateT =  crTypeSystem.getType("org.apache.uima.tutorial.DateAnnot");
    timeT =  crTypeSystem.getType("org.apache.uima.tutorial.TimeAnnot");

    //output types and features
    meetingT =  crTypeSystem.getType("org.apache.uima.tutorial.Meeting");

    if ( !(meetingT.isValid() && roomNumberT.isValid() && dateT.isValid() && timeT.isValid()) ) {
        getAnnotatorContext().getLogger().logError("typeSystemInit() Error getting Type objects");

	cout << "typeSystemInit() Error getting Type object" << endl;
	 return (TyErrorId) UIMA_ERR_RESMGR_INVALID_RESOURCE;
    }

    //get features
    roomF = meetingT.getFeatureByBaseName("room");
    dateF = meetingT.getFeatureByBaseName("date");
    startTimeF = meetingT.getFeatureByBaseName("startTime");
    endTimeF = meetingT.getFeatureByBaseName("endTime");

    if ( !(roomF.isValid() && dateF.isValid() && startTimeF.isValid() && endTimeF.isValid() ) ) {
	  getAnnotatorContext().getLogger().logError("typeSystemInit() Error getting Feature objects");
	  cout << "typeSystemInit() Error getting Feature  object" << endl;
	 return (TyErrorId) UIMA_ERR_RESMGR_INVALID_RESOURCE;
  }

    return (TyErrorId)UIMA_ERR_NONE;
  }

  /** */
  TyErrorId destroy()
  {
    cout << "MeetingAnnotator: destroy()" << endl;
    return (TyErrorId)UIMA_ERR_NONE;
  }

  /** */
  TyErrorId process(CAS & tcas, ResultSpecification const & crResultSpecification)
  {
    cout << "MeetingAnnotator: process()" << endl;

    //get annotation indexes
    FSIndexRepository & indexes = tcas.getIndexRepository();

    ANIndex roomNumberIndex = tcas.getAnnotationIndex(roomNumberT);
    ANIndex dateIndex = tcas.getAnnotationIndex(dateT);
    ANIndex timeIndex = tcas.getAnnotationIndex(timeT);

    //store end position of last meeting we identified, to prevent multiple
    //annotations over same span
    int lastMeetingEnd = -1;

    //iterate over all combinations
    ANIterator roomNumberIter = roomNumberIndex.iterator();
    roomNumberIter.moveToFirst();
    while (roomNumberIter.isValid()) {
      AnnotationFS room = roomNumberIter.get();

      ANIterator dateIter = dateIndex.iterator();
      dateIter.moveToFirst();

      while (dateIter.isValid()) {
        AnnotationFS date = dateIter.get();
        ANIterator time1Iter = timeIndex.iterator();
        time1Iter.moveToFirst();

        while (time1Iter.isValid()) {
          AnnotationFS time1 = time1Iter.get();
          ANIterator time2Iter = timeIndex.iterator();
          time2Iter.moveToFirst();

          while (time2Iter.isValid()) {
            AnnotationFS time2 = time2Iter.get();

            //times must be different annotations
            if (time1 != time2) {
              //compute the begin and end of the span
              int minBegin = min(
				  min(time1.getBeginPosition(), time2.getBeginPosition()),
				  min(date.getBeginPosition(), room.getBeginPosition()));

			  int maxEnd = max(
		  		  max(time1.getEndPosition(), time2.getEndPosition()),
		  		  max(date.getEndPosition(), room.getEndPosition()));

			  //span must be smaller than the window size?
			  if (maxEnd - minBegin < mWindowSize) {
				//span must not overlap the last annotation we made
				if (minBegin > lastMeetingEnd) {
				  //annotate
				  //Create Meeting FS and set the begin and end features
				  AnnotationFS mtg = tcas.createAnnotation(meetingT, minBegin, maxEnd);
				  //Set other four features
				  mtg.setFSValue(roomF, room);
				  mtg.setFSValue(dateF, date);
				  mtg.setFSValue(startTimeF, time1);
				  mtg.setFSValue(endTimeF, time2);

				  //add annotation to the index
				  indexes.addFS(mtg);
				  lastMeetingEnd = maxEnd;
				}
			  }
			}
			time2Iter.moveToNext();
			}
			time1Iter.moveToNext();
		  }
		  dateIter.moveToNext();
		}
		roomNumberIter.moveToNext();
	}
	return (TyErrorId)UIMA_ERR_NONE;
  }
};


// This macro exports an entry point that is used to create the annotator.

MAKE_AE(MeetingAnnotator);

