package yi.iu.processor.clc;

import yi.iu.processor.clc.*;
import yi.iu.processor.*;
import yi.iu.processor.building.*;
import yi.iu.processor.ort.*;
import yi.iu.processor.filter.GaussianSmooth;
import yi.iu.ui.*;
import yi.iu.processor.color.*;
import yi.util.io.*;
import yi.util.ImageUtil;
import yi.ds.Merge;

import java.awt.*;
import java.util.Vector;
import java.io.*;
import java.util.Date;

public class CSOSSM_br extends yi.iu.processor.clc.ConsistentLineCluster
{
    static double OVERLAPTHRSH=0.6;

    public int[] getProcessed(int source[], Dimension d)
    {
        return null;
    }

    public int[] getProcessedPseudoColor(int source[], Dimension d)
    {
        int i,j;

        //get the line clusters (classified by color information) stored in lc
        Object[] ref= new Object[4];
        CSOSSM csossm= new CSOSSM();
        LineCluster[] mlcs= csossm.getProcessed_ex(source, d, ref);
        int[] cluster_color= (int[])ref[0];
        int cNum=cluster_color.length;
        Vector lines= (Vector)ref[1];
        int[][] lineColor= (int[][])ref[2];

        //final process for building recognition
        LineCluster[] bCan= finalProcessBR(mlcs);

        //drawLineClusters("postMerge", d, mlcs, -1);
        /*
        //mark out the intersectant points
        for (i=0;i<intersects.size();i++) {
            ORTConjLineGroup clg= (ORTConjLineGroup)intersects.elementAt(i);
            double cx= clg.JunctionPt.Col, cy= clg.JunctionPt.Row;
            int index=(int)(Math.round(cy)*d.width+Math.round(cx));
            int color=0xffffffff;
            DrawUtil.drawMark(demo,d,(int)Math.round(cx),(int)Math.round(cy),4,color);
        }
        //mark out the no.1 line cluster
        if (bCans.size()>0) {
            LineCluster lcl= (LineCluster)bCans.elementAt(0);
            for (j=0;j<lcl.size();j++) {
                ORTLine line= lcl.getLineAt(j);
                DrawUtil.ort2image(demo, d, line, 0xff00ff00, 1);
            }
        }
        */
/*
        int[] label= new int[d.width*d.height];
        for (i=0;i<mlcs.length;i++) {
            if (mlcs[i]==null) continue;
            for (j=0;j<mlcs[i].size();j++) {
                ORTLine line= mlcs[i].getLineAt(j);
                DrawUtil.ort2image(label, d, line, i+1, 1);
            }
        }
        int[] demo= yi.util.ImageUtil.makeNewImageFromLabel(label);

        //get the boundary of the line clusters
        for (i=0;i<mlcs.length;i++) {
            if (mlcs[i]==null||mlcs[i].size()==0) continue;
            double[] b=mlcs[i].getBoundary();
            double minx=b[0], miny=b[1], maxx=b[2], maxy=b[3];
            DrawUtil.drawRectangle(demo, d, minx, miny, maxx, maxy, 0xffff0000, 2);
        }

        (new SegFrame("demo", demo, d.width, d.height, label)).show();
*/
        int[] label1= new int[d.width*d.height];
        for (i=0;i<label1.length;i++) label1[i]=-1;
        for (i=0;i<bCan.length;i++) {
            if (bCan[i]==null) continue;
            for (j=0;j<bCan[i].size();j++) {
                ORTLine line= bCan[i].getLineAt(j);
                DrawUtil.ort2image(label1, d, line, i, 2);
            }
        }
        int[] demo1= yi.util.ImageUtil.makeNewImageFromLabel_back(label1);

        //get the boundary of the line clusters
        for (i=0;i<bCan.length;i++) {
            if (bCan[i]==null||bCan[i].size()==0) continue;
            double[] b=bCan[i].getBoundary();
            double minx=b[0], miny=b[1], maxx=b[2], maxy=b[3];
            DrawUtil.drawRectangle(demo1, d, minx, miny, maxx, maxy, 0xffff0000, 3);
        }
/*
        //draw lines on the image directly
        int[] demo2=new int[source.length];
        for (i=0;i<source.length;i++) {
          demo2[i]= source[i] | 0x00808080;
          if (demo1[i]!=0xffffffff) demo2[i]=demo1[i];
        }

        (new SegFrame("demo", demo2, d.width, d.height, label1)).show();
*/
    //save the demo
    //Test.save(demo1,d);
    //OutputResult.outputColorImage(demo1, d.width, d.height);
        return demo1;
    }


    LineCluster[] finalProcessBR(LineCluster[] lcs)
    {
        int i,j;

        //filter the small line cluster
        filterSmallClusters(lcs);

        //combine the line clusters if there are overlap on vertical
        Vector cans= new Vector();
        for (i=0;i<lcs.length;i++)
            if (lcs[i]!=null&&lcs[i].size()>0) cans.addElement(lcs[i]);

        double[][] rects= new double[cans.size()][];
        for (i=0;i<cans.size();i++) {
            LineCluster lc=(LineCluster)cans.elementAt(i);
            rects[i]= lc.getBoundary();
        }

        Merge m= new Merge(rects.length);
        for (i=0;i<rects.length-1;i++) {
            for (j=i+1;j<rects.length;j++) {
                if (overlap(rects[i],rects[j])) m.merge(i, j);
            }
        }
        int[] mergerst= m.decentResult();
        int num=m.size();
        System.err.println("in final process: "+cans.size()+"->"+num);

        LineCluster[] rst= new LineCluster[num];
        for (i=0;i<num;i++) rst[i]=new LineCluster();

        for (i=0;i<mergerst.length;i++) {
            LineCluster lc2= (LineCluster)cans.elementAt(i);
            LineCluster lc1= rst[mergerst[i]];
            for (j=0;j<lc2.size();j++) {
                lc1.insert((ORTLine) lc2.getLineAt(j) );
            }
        }
        return rst;
    }

    boolean overlap (double[] r1, double[] r2)
    {
        double x1,x2,x3,x4;
        //x1<x3
        if (r1[0]<r2[0]) {
            x1=r1[0];
            x2=r1[2];
            x3=r2[0];
            x4=r2[2];
        }
        else {
            x1=r2[0];
            x2=r2[2];
            x3=r1[0];
            x4=r1[2];
        }
        if (x2<x1||x4<x3) {
            System.err.println("!!!wrong rect argus");
        }
        if (x2<=x3) return false;
        double overlap= Math.min(x2-x3, x4-x3);
        double minw= Math.min(x2-x1, x4-x3);
        if (overlap/minw>=OVERLAPTHRSH) return true;
        else return false;
    }

    public static void main(String[] args)
    {
        String directory="images";
        if (args.length>0) {
            directory=args[0];
            System.err.println("directory name = "+directory);
        }
        //String images[]= yi.util.io.File.getFileNames(directory);
        String images[]= yi.util.io.File.getImagesNameRecursively(directory);
        System.err.println("Image#="+images.length);

        ConsistentLineCluster br= new CSOSSM_br();
        double[] running_time= new double[images.length];

        for (int i=0;i<images.length;i++) {
            java.util.Date date= new Date();
            String imageName= images[i];
            System.err.println();
            System.err.println("==== "+imageName+" ==== "+(i+1)+"/"+images.length);
            Dimension d= new Dimension();
            int[] source= yi.util.ImageUtil.readImage(imageName, d);
            if (source==null) continue;
            int[] result= br.getProcessedPseudoColor(source, d);
            String newName;
            int index=imageName.lastIndexOf(".jpg");
            if (index<0) index=imageName.lastIndexOf(".JPG");
            if (index<0) index=imageName.lastIndexOf(".ppm");
            if (index<0) index=imageName.lastIndexOf(".PPM");
            if (index>=0) newName= imageName.substring(0,index)+"_rst.gif";
            else newName= imageName+"_rst.gif";
            System.err.println("output: "+newName);
            //yi.util.io.OutputResult.outputColorImage(newName, result, d.width, d.height);
            yi.util.io.OutputResult.outputGIFImage(newName, result, d.width, d.height);
            source=null;result=null;
            System.gc();
            java.util.Date date2= new Date();
            running_time[i]= date2.getTime()-date.getTime();
            System.err.println("time elapse: "+(running_time[i])/1000.0);

        }
        OutputResult.outputResult("timing",running_time,1,running_time.length );
        System.err.println();
        System.err.println("Done!");
        System.exit(0);
    }

}