package yi.iu.processor.symmetry;

import java.awt.*;
import yi.iu.processor.ImageProcessor;
import yi.iu.ui.DisplayFrame;

public class SymmetryFinder extends ContourBasedSymProcessor
{
    ContourBasedSymProcessor csc, gsc, hsc;
    
    public SymmetryFinder() {
        csc= new ContourSymmetryCal();
        gsc= new GrayLevelSymmetryCal();
        hsc= new HorizontalLineSymCal();
    }
    
    public SymmetryFinder(String edgeDectorName) {
        csc= new ContourSymmetryCal(edgeDectorName);
        gsc= new GrayLevelSymmetryCal(edgeDectorName);
        hsc= new HorizontalLineSymCal(edgeDectorName);
    }
    
    public int[] getProcessedPseudoColor(int source[],  Dimension d)
    {
        int[] result=new int[source.length];
        int w=d.width, h=d.height;
        int[] rst= getProcessed(source,d);
        int nw=d.width, nh=d.height;
        d.width=w; d.height=h;
        int z=w/nw;
        
        for (int i=0;i<w*h;i++) result[i]= source[i];
        for (int i=0;i<nw;i++) {
            if (rst[i]==0) continue;
            for (int j=0;j<h;j++) {
                if (rst[i]==1)
                    //break;
                    result[j*w+i*z+1]= result[j*w+i*z+2]= 0xffff0000;
                else if (rst[i]==2)
                    result[j*w+i*z+1]= result[j*w+i*z+2]= 0xff00ff00;
                else
                    result[j*w+i*z+1]= result[j*w+i*z+2]= 0xff0000ff;
            }
        }
        //DisplayFrame f= new DisplayFrame(result, w, h);
        //f.show();
        return result;
    }

    public int[] getProcessed(int source[], Dimension d, int maxWidth)
    {
        
        Dimension oldD= new Dimension(d);
        int[] cs= csc.getProcessed(source, d, maxWidth);
        int oldw=oldD.width, neww=d.width;
        int size=oldw/neww;    // region size when doing mean deviation
        d.width= oldD.width; d.height= oldD.height;
        int[] gs= gsc.getProcessed(source, d, maxWidth);
        d.width= oldD.width; d.height= oldD.height;
        int[] hs= hsc.getProcessed(source, d, maxWidth);
        d.width= oldD.width; d.height= oldD.height;
        
        // find the local maxima
        int[] csmax= yi.dp.Histogram.getLocalMaxima(cs,maximaSize,MAXIMATHRESHOLD);
        int[] gsmax= yi.dp.Histogram.getLocalMaxima(gs,maximaSize,MAXIMATHRESHOLD);
        int[] hsmax= yi.dp.Histogram.getLocalMaxima(hs,maximaSize,MAXIMATHRESHOLD);
        
        // find the common maxima among the three
        int[] maxima= new int[csmax.length];
        for (int i=0;i<csmax.length;i++) {
            maxima[i]+= csmax[i];
            maxima[i]+= gsmax[i];
            maxima[i]+= hsmax[i];
        }

        // retrun the axis with the max vote
        /*
        // find the symmetric axis
        int[] symAxis= new int[oldw];
        boolean found= false;
        for (int i=0;i<neww;i++)
            if (maxima[i]==3) {
                found= true;
                symAxis[i*size+(size/2)]=1;
            }
        if (!found) {
            for (int i=0;i<neww;i++)
                if (maxima[i]==2) {
                    found= true;
                    symAxis[i*size+(size/2)]=1;
                }
        }
        if (!found) {
            for (int i=0;i<neww;i++)
                if (maxima[i]==1) {
                    found= true;
                    symAxis[i*size+(size/2)]=1;
                }
        }
        */
        
        // alternative, return the vote
        
        int[] symAxis= new int[oldw];
        for (int i=0;i<neww;i++)
            if (maxima[i]>0)
                symAxis[i*size+(size/2)]=maxima[i];
        
        
        // alternatively, we can return a high value, if all the three vote the neibhour
        for (int i=0;i<neww;i++) {
            if (maxima[i]==0) continue;
            int add=0;
            if (csmax[i]==0) {
                if (i==0) { if (csmax[i+1]>0) add++;}
                else if (i==neww-1) { if (csmax[i-1]>0) add++;}
                else { if (csmax[i-1]>0||csmax[i+1]>0) add++;}
            }
            if (gsmax[i]==0) {
                if (i==0) { if (gsmax[i+1]>0) add++;}
                else if (i==neww-1) { if (gsmax[i-1]>0) add++;}
                else { if (gsmax[i-1]>0||gsmax[i+1]>0) add++;}
            }     
            if (hsmax[i]==0) {
                if (i==0) { if (hsmax[i+1]>0) add++;}
                else if (i==neww-1) { if (hsmax[i-1]>0) add++;}
                else { if (hsmax[i-1]>0||hsmax[i+1]>0) add++;}
            }
            maxima[i]+=add;
            symAxis[i*size+(size/2)]=maxima[i];
        }
        d.width= symAxis.length; d.height=1;
        return symAxis;
    }
    

}