package ipipan.poliqarp.stat;

import ipipan.poliqarp.logic.Interpretation;
import ipipan.poliqarp.logic.Segment;

/**
 * Class representing a single part of grouping rules, one attribute
 * of one segment.  SelectorPart consists of an optional segment
 * number (default 1) and attribute name.  Examples:
 * <ol><li>base</li><li>3.orth</li><li>-1.case</li></ol>.
 * SelectorPart also needs a Tagset as a context defining whether a
 * given part of speech has a specific attribute, aliases for
 * attributes etc.
 */
public class SelectorPart {
   static final int BY_ORTH = 1;
   static final int BY_BASE = 2;
   static final int BY_OLEN = 3;
   static final int BY_CTAG = 4;

   static final int REQ_ORTH  = 1;
   static final int REQ_LEMM = 2;
   static final int REQ_TAGS  = 4;

   int segno;
   int type;
   String attr;
   Tagset tagset;
   int requirements;

   /**
    * Creates a new SelectorPart.
    * @param part a string representation of the part.
    * @param ts tagset for which the selector part is constructed.
    */
   public SelectorPart(String part, Tagset ts)
   throws StatQueryException {
      tagset = ts;
      String[] h = part.split("\\.");
      if (h.length > 2);
      if (h.length == 2) {
         segno = Util.safeParseInt(h[0], 1);
         if (segno == 0)
            segno = 1;
         setType(h[1]);
      } else {
         segno = 1;
         setType(h[0]);
      }
   }

   void setType(String s)
   throws StatQueryException {
      if (s.equalsIgnoreCase("orth")) {
         type = BY_ORTH;
         requirements = REQ_ORTH;
         return;
      }

      if (s.equalsIgnoreCase("length")) {
         type = BY_OLEN;
         requirements = REQ_ORTH;
         return;
      }

      if (s.equalsIgnoreCase("base")) {
         type = BY_BASE;
         requirements = REQ_LEMM;
         return;
      }

      type = BY_CTAG;
      requirements = REQ_TAGS;
      attr = tagset.getBaseName(s);
      if (attr == null) {
         System.err.println("SelectorPart.setType(): <"+s+"> not in tagset>");
         throw new StatQueryException();
      }
   }

   /**
    * @return segment number defined during the creation of the SelectorPart
    */
   public int getSegno() {
      return segno;
   }

   /**
    * @return requirements for segment transmission
    */
   public int getRequirements() {
      return requirements;
   }

   /**
    * @param segm
    * @return depending on the type of the SelectorPart: orth of a
    * match, length of the orth or null if the selector needs to
    * check an Interpretation rather than a Match.
    */
   public String orthValue(Segment segm) {
      if (type == BY_ORTH)
         return segm.getOrth().toLowerCase().trim();

      if (type == BY_OLEN)
         return String.valueOf(segm.getOrth().trim().length());

      return null;
   }

   /**
    * @param interp
    * @return value of a specific attribute from the interpretation
    */
   public String tagValue(Interpretation interp) {
      if (type == BY_ORTH)
         return null;

      if (type == BY_BASE)
         return interp.getLemma();

      return tagset.getAttrValue(interp.getTag(), attr);
   }
}

