package yi.iu.ft.local;

import java.util.Iterator;
import yi.iu.region.Region;
import yi.util.io.input.*;
import yi.util.io.output.*;

public class RegionSpatialRelation implements RegionBased, IsLocalFeature{
  RegionBased m_region1, m_region2;
  Region m_combinedRegion;
  double m_direction, m_distance;

  public RegionSpatialRelation(RegionBased rb1, RegionBased rb2) {
    m_region1 = rb1;
    m_region2 = rb2;
    Region r1 = rb1.getRegion(), r2 = rb2.getRegion();
    m_combinedRegion = Region.combine(r1, r2);
    m_direction = direction(r1.m_centroidX, r1.m_centroidY, r2.m_centroidX, r2.m_centroidY);
    m_distance = distance(r1.m_centroidX, r1.m_centroidY, r2.m_centroidX, r2.m_centroidY);
  }

  public Region getRegion() {
    return m_combinedRegion;
  }

  double direction(double x1, double y1, double x2, double y2) {
    return Math.atan2(y2-y1, x2-x1);
  }

  double distance(double x1, double y1, double x2, double y2) {
    double dx=x1-x2, dy=y1-y2;
    return Math.sqrt(dx*dx+dy*dy);
  }

  double getNormalizedDistance() {
    double radius1 = Math.sqrt(m_region1.getRegion().m_size/Math.PI);
    double radius2 = Math.sqrt(m_region2.getRegion().m_size/Math.PI);
    return m_distance/(radius1 + radius2);
  }

  int ATTIBUTE_NUM = 5;

  /**
   * direction, distance, region.x, region.y, region.size
   * @return
   */
  public int getAttributeNum() {
    return ATTIBUTE_NUM;
  }

  public Iterator listAttributes() {
    String[] s = {
      "direction",
      "distance",
      "x",
      "y",
      "size"
    };
    return java.util.Arrays.asList(s).iterator();
  }

  public GlobalizationTempl getDefaultGlobalizationTemp() {
    GlobalizationTemplImpl templ = null;
    try {
      templ = (GlobalizationTemplImpl)DIU.in(
                DIU.INPUT_XML,
                "",
                DOU.shortName(this.getClass().getName()),
                "GlobalizationTemplImpl",
                Class.forName("yi.iu.ft.local.GlobalizationTemplImpl"));
      if (templ != null) return templ;
    } catch (DataInputException e) {
      // just ignore the exceptions
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }

    // construct the default template
    templ = new GlobalizationTemplImpl(ATTIBUTE_NUM);
    // direction
    templ.setAttributeOn(0, 0, Math.PI/2, 4);
    // distance
    templ.setAttributeOn(1, 0, 1, 3);
    // x,y - [0,1) divided by 2 bins
    templ.setAttributeOn(2, 0, 0.5, 2);
    templ.setAttributeOn(3, 0, 0.5, 2);
    // size
    templ.setAttributeOn(4, 0, 0.5, 2);

    //
    for (int i=0; i<ATTIBUTE_NUM; i++) {
      for (int j=0; j<ATTIBUTE_NUM; j++) {
        if (i==j) templ.addStatsOn(i, j, yi.stat.hist.Hist.COUNT);
        else templ.addStatsOn(i, j, GlobalizationTemplImpl.NONE);
      }
    }
    try {
      DOU.out(DOU.OUTPUT_XML,
              "",
              DOU.shortName(this.getClass().getName()),
              "GlobalizationTemplImpl",
              templ);
    } catch (DataOutputException e) {
      e.printStackTrace();
    }
    return templ;
  }

}