package yi.iu.processor.clc;

import java.util.*;
import yi.iu.processor.ort.*;

/**
 * Calculate and store the interrelationship of two line clusters.  The saved
 * information includes intersecting point numbers and intersecting line numbers
 * from two line clusters and intersecting line weighted length total from two
 * line clusters
 */
public class Interrelationship implements java.io.Serializable{

  public int m_intersectNum;
  public int m_intersectingLineNum1, m_intersectingLineNum2;
  public double m_intersectingLineWeightedLenTotal1, m_intersectingLineWeightedLenTotal2;
  public int m_lineNum1, m_lineNum2;

  public LineClusterSet m_intersectingLines1, m_intersectingLines2;

  public Interrelationship(int intersect_num, int intersecting_line_num1, int intersecting_line_num2,
    double intersecting_line_weighted_len_total1, double intersecting_line_weighted_len_total2,
    int line_num1, int line_num2, LineClusterSet intersectingLines1,
    LineClusterSet intersectingLines2) {
      m_intersectNum = intersect_num;
      m_intersectingLineNum1 = intersecting_line_num1;
      m_intersectingLineNum2 = intersecting_line_num2;
      m_intersectingLineWeightedLenTotal1 = intersecting_line_weighted_len_total1;
      m_intersectingLineWeightedLenTotal2 = intersecting_line_weighted_len_total2;
      m_lineNum1 = line_num1;
      m_lineNum2 = line_num2;
      m_intersectingLines1 = intersectingLines1;
      m_intersectingLines2 = intersectingLines2;
  }

  public static Interrelationship interrelation(LineClusterSet lc1, LineClusterSet lc2) {

    boolean[] tinter= new boolean[lc1.size()];
    java.util.Arrays.fill (tinter, false);

    boolean[] tinter2 = new boolean[lc2.size()];
    java.util.Arrays.fill (tinter2, false);

    LineClusterSet intersectingLines1 = lc1.newInstanceWithSameProperties();
    LineClusterSet intersectingLines2 = lc2.newInstanceWithSameProperties();

    int intersectNum = 0;   // intersection number made by two clusters

    Iterator i = lc1.iterator();

    for (int i_count = 0; i.hasNext(); i_count++) {

        ORTLine l1 = (ORTLine)i.next(); // line in cluster 1

        Iterator j = lc2.iterator();
        for (int j_count = 0; j.hasNext(); j_count++) {

            ORTLine l2 = (ORTLine)j.next(); // line in cluster 2

            // the relationship between two lines:
            //   MaxWidthOverHeight = 2.0;   useless in junction type
            //   MinLineLength = 4.0;  if the length of any line < this value, return null
            //   MinDeltaTheta = 0.06; [0,this]:parallel, [this,pi/2]:junction
            //   MinDeltaTheta = 0.35; (20 degree) to only consider the good intersect
            //   MinQuality    = 0.8;  if the quaulity of the group < this value, return null
            //   LooseRatio= 2
            ORTLineGroup lg= Lpeg.loose_lineRelation_closeJunction(l1, l2, 2, 4, 0.35, 0.8, 2);

            if (lg == null) continue;
            else { // they are intersected
                tinter[i_count] = true;
                tinter2[j_count] = true;
                //intersects.addElement(lg);
                intersectNum ++;
                intersectingLines1.add(l1);
                intersectingLines2.add(l2);
            }
        }
    }

    double weightedInter = 0, weightedInter2 = 0;
    // intersecting line number in cluster-i and cluster-j
    int interCount=0, interCount2 = 0;

    // statistical calculation
    i = lc1.iterator();
    for (int i_count = 0; i.hasNext(); i_count++) {
      ORTLine l = (ORTLine)i.next();
      if (tinter[i_count]) {
        interCount ++;
        weightedInter += CLCUtil.lineWeight(l.Length);
      }
    }

    i = lc2.iterator();
    for (int i_count = 0; i.hasNext(); i_count++)  {
      ORTLine l = (ORTLine)i.next();
      if (tinter2[i_count]) {
        interCount2 ++;
        weightedInter2 += CLCUtil.lineWeight(l.Length);
      }
    }
    return new Interrelationship(
      intersectNum,
      interCount, interCount2,
      weightedInter, weightedInter2,
      lc1.size(), lc2.size(), intersectingLines1, intersectingLines2);

  }

  public String toString() {
    return "" + m_intersectingLineNum1 + "/" + m_lineNum1 + ": " +
        m_intersectingLineNum2 + "/" +m_lineNum2;

  }
}