package yi.or;

import yi.iu.processor.*;
import yi.iu.processor.morph.*;
import yi.iu.processor.channel.*;
import yi.iu.processor.texture.*;
import yi.iu.processor.graphseg.*;
import yi.util.io.OutputResult;

import java.awt.*;
public class RegionInfo extends yi.iu.processor.ImageProcessor
{
    boolean VERBOSE=true;

    //the two arguments below are used to calculate the laws texture information for the specified region
    //because the calculationg of laws texture energy involves making means among the neighbour, so it is
    //not the representive value on the boundary.  e.g. if the energy calculation involves 15*15 block, then
    //the value within the boundary stripe with 7-pixel width are mixed with the value of the pixels outside
    //the region.
    int LAWS_ENER_PAD_LENGTH=7;  //make average in 15*15 block
    //the color values on the boundary between two different object are often diffused, it is desirable that
    //consider the enfluence
    int DIFFUSE_BOUNDARY_W=2;    //for calculate hsi information and laws energy information

    public int[] getProcessed(int source[], Dimension d)
    {
        // This method is derived from class yi.iu.processor.ImageProcessor
        // to do: code goes here
        return null;
    }

    public int[] getProcessedPseudoColor(int source[], Dimension d)
    {
        if (VERBOSE) System.err.println("segment...");
        int[] seg_1= (new GS_HCI()).segmentation(source, d.width, d.height, DISTANCE_THRESHOLD, BSCRGNSIZE, STOPRGNSIZE);
        int[][] seg= yi.util.ImageUtil.oneD2twoD(seg_1, d);
        Region rgn= new Region(seg);
        rgn.enable0();
        rgn.removeSmallRegion(100);
        rgn.display(source);

        if (rgn1>=0) {
            //find the target region
            Region target= new Region(rgn, rgn1);
            //possibly,target region= region_1 + region_2
            if (rgn2>=0) {
                Region tar2= new Region(rgn, rgn2);
                target.union(tar2);
            }
            target.display(source);

            //erose the region to eliminate the diffusiong effect on the boundary
            target.erosion(Morph.BLOCK, DIFFUSE_BOUNDARY_W*2+1);

            //calculate the hsi information
            if (VERBOSE) System.err.println("hsi infomation...");
            int[][] hsi= (new CYMaker()).getProcessed_ex(source, d);
            int[][] stat_hsi= target.getInfoStat(hsi);

            //calculate the laws texture information
            if (VERBOSE) System.err.println("laws infomation...");
            Region small_tar= new Region(target);
            //erose the region to eliminate the effect from mean calculation
            int erosion_r= LAWS_ENER_PAD_LENGTH*2+1;
            small_tar.erosion(Morph.BLOCK, erosion_r);
            int[][] laws= (new LawsMaker()).getProcessed_ex(source, d, LAWS_ENER_PAD_LENGTH);
            int[][] stat_laws= small_tar.getInfoStat(laws);
            small_tar.display();

            //the diff information seems to be useless
            //calculate the diff information
            //if (VERBOSE) System.err.println("diff infomation...");
            //int[][] diff= (new DiffMaker()).getProcessed_ex(source, d);
            //int[][] stat_diff= target.getInfoStat(diff);

            //calculate the statistic informatio of that region
            if (VERBOSE) System.err.println("stat infomation...");
            double[][] stat= target.getStatistics(1);

            OutputResult.outputResult("stat_hsi",stat_hsi);
            OutputResult.outputResult("stat_laws",stat_laws);
            //OutputResult.outputResult("stat_diff",stat_diff);
            OutputResult.outputResult("stat_rgn",stat);
        }
        if (VERBOSE) System.err.println("done.\n");
        return null;
    }

    public int BSCRGNSIZE= 8;  //the basic region size, now try to define as 8*8
    public int STOPRGNSIZE= 1;  //after the refine, what's size of the basic block
    public int DISTANCE_THRESHOLD= 72;   //the max allowed distance for two basic region grow in the first step


    int rgn1=-1;
    int rgn2=-1;

    public int getArguNum() { return 7;}

    public void setArgument(int i, String st)
    {
        if (st.length()==0) return;
        if (i==0) {
            DISTANCE_THRESHOLD= Integer.valueOf(st).intValue();
        }
        if (i==1) {
            BSCRGNSIZE= Integer.valueOf(st).intValue();
        }
        if (i==2) {
            STOPRGNSIZE= Integer.valueOf(st).intValue();
        }

        if (i==3) {
            rgn1= Integer.valueOf(st).intValue();
        }
        if (i==4) {
            rgn2= Integer.valueOf(st).intValue();
        }

        if (i==5) {
            LAWS_ENER_PAD_LENGTH= Integer.valueOf(st).intValue();
        }
        if (i==6) {
            DIFFUSE_BOUNDARY_W= Integer.valueOf(st).intValue();
        }
    }


    public String getArgument(int i)
    {
        if (i==0) return (new Integer(DISTANCE_THRESHOLD)).toString();
        if (i==1) return (new Integer(BSCRGNSIZE)).toString();
        if (i==2) return (new Integer(STOPRGNSIZE)).toString();

        if (i==3) return (new Integer(rgn1)).toString();
        if (i==4) return (new Integer(rgn2)).toString();

        if (i==5) return (new Integer(LAWS_ENER_PAD_LENGTH)).toString();
        if (i==6) return (new Integer(DIFFUSE_BOUNDARY_W)).toString();

        return null;
    }

    public String getArguName(int i)
    {
        if (i==0) return "diff_threshold";
        if (i==1) return "basic region size";
        if (i==2) return "stop region size";

        if (i==3) return "target rgn";
        if (i==4) return "extra rgn";

        if (i==5) return "laws en_pad_len";
        if (i==6) return "diffuse_width";

        return null;
    }

}