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

package opennlp.tools.disambiguator.ims;

import java.util.ArrayList;
import java.util.List;

import net.sf.extjwnl.data.POS;
import opennlp.tools.disambiguator.WSDHelper;
import opennlp.tools.disambiguator.WSDSample;

public class WTDIMS {

  // Attributes related to the context
  protected String[] sentence;
  protected String[] posTags;
  protected String[] lemmas;
  protected int wordIndex;
  protected int sense;
  protected List<String> senseIDs;

  // Attributes related to IMS features
  protected String[] posOfSurroundingWords;
  protected String[] surroundingWords;
  protected String[] localCollocations;
  protected String[] features;

  public WTDIMS(String[] sentence, String[] posTags, String[] lemmas,
      int wordIndex) {
    this.sentence = sentence;
    this.posTags = posTags;
    this.wordIndex = wordIndex;
    this.lemmas = lemmas;
  }

  public WTDIMS(String[] sentence, String[] posTags, String[] lemmas,
      int wordIndex, List<String> senseIDs) {
    this.sentence = sentence;
    this.posTags = posTags;
    this.wordIndex = wordIndex;
    this.lemmas = lemmas;
    this.senseIDs = senseIDs;

  }

  public WTDIMS(String[] sentence, String[] posTags, String[] lemmas,
      String word, List<String> senseIDs) {
    super();

    this.sentence = sentence;
    this.posTags = posTags;
    this.lemmas = lemmas;

    for (int i = 0; i < sentence.length; i++) {
      if (word.equals(sentence[i])) {
        this.wordIndex = i;
        break;
      }
    }

    this.senseIDs = senseIDs;

  }

  public WTDIMS(WSDSample sample) {
    this.sentence = sample.getSentence();
    this.posTags = sample.getTags();
    this.lemmas = sample.getLemmas();
    this.wordIndex = sample.getTargetPosition();
    this.senseIDs = sample.getSenseIDs();

  }
  
  public String[] getSentence() {
    return sentence;
  }

  public void setSentence(String[] sentence) {
    this.sentence = sentence;
  }

  public String[] getPosTags() {
    return posTags;
  }

  public void setPosTags(String[] posTags) {
    this.posTags = posTags;
  }

  public int getWordIndex() {
    return wordIndex;
  }

  public void setWordIndex(int wordIndex) {
    this.wordIndex = wordIndex;
  }

  public String[] getLemmas() {
    return lemmas;
  }

  public void setLemmas(String[] lemmas) {
    this.lemmas = lemmas;
  }

  public int getSense() {
    return sense;
  }

  public void setSense(int sense) {
    this.sense = sense;
  }

  public List<String> getSenseIDs() {
    return senseIDs;
  }

  public void setSenseIDs(ArrayList<String> senseIDs) {
    this.senseIDs = senseIDs;
  }

  public String getWord() {
    return this.getSentence()[this.getWordIndex()];
  }

  public String getWordTag() {

    String wordBaseForm = this.getLemmas()[this.getWordIndex()];

    String ref = "";

    if ((WSDHelper.getPOS(this.getPosTags()[this.getWordIndex()]) != null)) {
      if (WSDHelper.getPOS(this.getPosTags()[this.getWordIndex()]).equals(
          POS.VERB)) {
        ref = wordBaseForm + ".v";
      } else if (WSDHelper.getPOS(this.getPosTags()[this.getWordIndex()])
          .equals(POS.NOUN)) {
        ref = wordBaseForm + ".n";
      } else if (WSDHelper.getPOS(this.getPosTags()[this.getWordIndex()])
          .equals(POS.ADJECTIVE)) {
        ref = wordBaseForm + ".a";
      } else if (WSDHelper.getPOS(this.getPosTags()[this.getWordIndex()])
          .equals(POS.ADVERB)) {
        ref = wordBaseForm + ".r";
      }
    }

    return ref;
  }

  
  public String[] getPosOfSurroundingWords() {
    return posOfSurroundingWords;
  }

  public void setPosOfSurroundingWords(String[] posOfSurroundingWords) {
    this.posOfSurroundingWords = posOfSurroundingWords;
  }

  public String[] getSurroundingWords() {
    return surroundingWords;
  }

  public void setSurroundingWords(String[] surroundingWords) {
    this.surroundingWords = surroundingWords;
  }

  public String[] getLocalCollocations() {
    return localCollocations;
  }

  public void setLocalCollocations(String[] localCollocations) {
    this.localCollocations = localCollocations;
  }

  public String[] getFeatures() {
    return this.features;
  }

  public void setFeatures(String[] features) {
    this.features = features;
  }

}
