/*
 * Jpeg2000Demo.java
 *
 * Created on 15 listopad 2004, 20:32
 */


import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import java.net.*;
import java.util.Locale;
import java.io.*;
//import org.cemte.jacek.przetwarzanie.mat.*;
//import org.cemte.jacek.przetwarzanie.filtr.*;
/**
 *
 * @author  W�a�ciciel
 */


class ImagePanel extends JPanel{
    Image img;
    
    public ImagePanel(Image img){
        this.img=img;
    }
    public ImagePanel(){
    
    }
    public void setImage(Image img){
        this.img=img;
    }
    public void paint(Graphics g){
        if(img!=null)
            
            g.drawImage(img,0,0,null);
       
    }
   
}//end of ImagePanel

public class Jpeg2000Demo extends JFrame{
    
    public static final String INFO="Praca w trybie klienta: Poda� adres IP serwera i wcisn�� \"Receive\"\nPraca w trybie serwera: Otworzy� obraz \"Open image\" a nast�pnie \"Start serwer\"";
    
    public ImagePanel imagePanel=new ImagePanel();
    public ImagePanel mrwPanel=new ImagePanel();
    public JTextArea infoArea=new JTextArea(INFO);
    public JPanel controlPanel=new JPanel();
    public JButton nextBP=new JButton("Next BP");
    public JButton prevBP=new JButton("Prev BP");
    public JButton moreBanks=new JButton("More banks");
    public JButton lessBanks=new JButton("Less banks");
    public JButton openImage=new JButton("Open image");
    public JButton startServer=new JButton("Start server");
    public JButton receive=new JButton("Receive");
    public JButton end=new JButton("Exit");
    public JTextField ipAddress = new JTextField("ZAMIAST TEGO TEKSTU WPISZ ADRES IP SERWERA!");
    JPanel leftPanel = new JPanel();
    JPanel rightPanel = new JPanel();
    public static File katalog=null;
    public PrintStream log=System.out;
    
    public int[] imageData;
    public double[] data;
    public int w;
    public int h;
    public JFrame parent;
    
    
    
    /** Creates a new instance of Jpeg2000Demo */
    public Jpeg2000Demo() {
        super("Wymiana obraz�w z zastosowaniem dekompozycji falkowej i kwantyzacji JPEG2000 - Jacek Ruminski, 2004");
        parent=this;
        init();
    }
    
    public void init(){
        
        JPanel infoGroup = new JPanel();
        infoGroup.setLayout(new GridLayout(2,1));
        setLayout(new GridLayout(1,2));
        leftPanel.setLayout(new BorderLayout());
        rightPanel.setLayout(new BorderLayout());
        getContentPane().add(leftPanel);
        getContentPane().add(rightPanel);
        
        
        leftPanel.add(imagePanel,BorderLayout.CENTER);
        
        infoGroup.add(ipAddress);
        infoGroup.add(infoArea);
        leftPanel.add(infoGroup,BorderLayout.SOUTH);
        
        rightPanel.add(mrwPanel,BorderLayout.CENTER);
        rightPanel.add(controlPanel,BorderLayout.SOUTH);
        controlPanel.setLayout(new GridLayout(2,4));
        controlPanel.add(nextBP);
        controlPanel.add(prevBP);
        controlPanel.add(moreBanks);
        controlPanel.add(lessBanks);
        controlPanel.add(openImage);
        controlPanel.add(startServer);
        controlPanel.add(receive);
        end.setForeground(Color.red);
        controlPanel.add(end);
        
        imagePanel.setPreferredSize(new Dimension(512, 512));
        mrwPanel.setPreferredSize(new Dimension(512, 512));
        
        end.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent ae){
                shutdown();
            }
        });
        
        openImage.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent ae){
                URL imageFileURL=openFileDialog();
                //Image img = Toolkit.getImage(imageFileURL);                
                if(imageFileURL!=null){
                    Image img = Toolkit.getDefaultToolkit().getImage(imageFileURL); 
                    MediaTracker mt = new MediaTracker(parent);
                    mt.addImage(img,0);
                    if (mt.isErrorAny()) System.out.println("B��D �ADOWANIA OBRAZU");
                    try { mt.waitForID(0); }
                    catch (InterruptedException ie) {return;  }
                    if (mt.isErrorID(0)) return;
                    w = img.getWidth(null);
                    h = img.getHeight(null);
                    if((w>512)||(h>512)){
                        JOptionPane.showMessageDialog(parent,new String("Obraz za du�y skaluje do rozmiaru do 512/512"),new String("OSRZE�ENIE !"),JOptionPane.WARNING_MESSAGE);
                        double scale=1;
                        if(w>=h)
                            scale=w/512.0;
                        else  
                            scale=h/512.0;
                        w=(int)(w/scale);
                        h=(int)(h/scale);
                        img=img.getScaledInstance(w,h,Image.SCALE_SMOOTH);
                        mt = new MediaTracker(parent);
                        mt.addImage(img,0);
                        if (mt.isErrorAny()) System.out.println("B��D �ADOWANIA OBRAZU");
                        try { mt.waitForID(0); }
                        catch (InterruptedException ie) {return;  }
                        if (mt.isErrorID(0)) return;
                    }
                    
                    BufferedImage bObraz = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
                    Graphics2D big = bObraz.createGraphics();
                    big.drawImage(img,0,0,null);
                    bI_to_int(bObraz);
                    resetImagePanel();
                    addWaveletPanel(imageData);
                    //ob=new Obraz(bObraz);
                }
                    //openImage(imageFileURL);
                
            }
        });
        
    }
    
    public static void main (String args[]){
        Jpeg2000Demo jp = new Jpeg2000Demo();
        jp. setSize(1024,768);
        jp.setVisible(true);
    }//end of main()
    
    private URL openFileDialog(){
        URL fileURL=null;
        boolean cancel=false;
        try{
            JFileChooser chooser = new JFileChooser();
            if (Jpeg2000Demo.katalog!=null)
                   chooser.setCurrentDirectory(Jpeg2000Demo.katalog);

            chooser.setLocation(this.getWidth()+10,0);
            chooser.setBackground(Color.black);
            chooser.setDialogTitle("OTW�RZ");
            chooser.setApproveButtonText("OTW�RZ");
            chooser.setToolTipText("Tekst");
            chooser.setDefaultLocale(new Locale("pl","PL"));
            int returnVal = chooser.showOpenDialog(this);
            
            if(returnVal == JFileChooser.APPROVE_OPTION) {
                  File file=chooser.getSelectedFile();
                  fileURL=new URL("file","localhost",file.getAbsolutePath());
                  log.println("OTO URL: "+fileURL);
            }else
                   cancel=true;
            Jpeg2000Demo.katalog=chooser.getCurrentDirectory();
            log.println("KATALOG: "+Jpeg2000Demo.katalog.getAbsolutePath());
        }catch(Exception e){
            if(!cancel)
                log.println("B��d dost�pu do pliku, przy pr�bie jego otwarcia! Kod"+e);
        }
 


        return fileURL;
    }//private URL openFileDialog(){
    
    public static void shutdown(){
        System.exit(1);
    }//shutdown()
    
     /**
    * bI_to_int - metoda pobrania warto�ci macierzy obrazu (macierzObrazu) z jego 
    * reprezentacji w formie BufferedImage, do postaci macierz luminancji 
    * Y=(R+G+B)/3
    */
    public void bI_to_int(BufferedImage bOb){
            /*
            int w=bOb.getWidth();
            int h=bOb.getHeight();
            this.w=w;
            this.h=h;
             */
             log.println("Width:"+w);
             log.println("Height:"+h);
            int MAX=Integer.MIN_VALUE;
            int MIN=Integer.MAX_VALUE;
            //int [][]mob=new int[h][w];
            imageData=new int[w*h];
            data=new double[w*h];
            int pixel=0;
            int R=0,G=0,B=0;
            for(int i=0;i<w;i++){
                    for(int j=0;j<h;j++){
                            pixel=bOb.getRGB(i,j);
                            B=pixel&0xFF;
                            G=(pixel>>8)&0xFF;
                            R=(pixel>>16)&0xFF;
                            //mob[j][i]=(R+G+B)/3;
                            int l=(R+G+B)/3;
                            data[j*w+i]=(double)l;
                            imageData[j*w+i]=(255 << 24)| (l << 16) |(l << 8) | l;
                            if (l>MAX) MAX=l;
                            if (l<MIN) MIN=l;
                            //if (mob[j][i]>MAX) MAX=mob[j][i];
                            //if (mob[j][i]<MIN) MIN=mob[j][i];
                    }
            }
           
            //imageData=Macierz.macWektor(h,w,mob);
            //mob=new int[1][1];
    }// koniec bI_to_int
    
    public void resetImagePanel(){
        //Graphics g=imagePanel.getGraphics();
        Image img=produceImage(imageData, w,h);
        imagePanel.setImage(img);
        validate();
        repaint();
    
    }//end of resetImagePanel
    
    public void addWaveletPanel(int []imageData){
        //mrwPanel=new ImagePanel();
        
        Jpeg2000Procesor jp = new Jpeg2000Procesor(5);
        double [][] dataTMP = new double[h][w];
        int offset=1;
        for(int i=0; i<h; i++){
            offset=i*w;
             for(int j=0; j<w; j++){
                 dataTMP[i][j]= data[offset+j];
                 //if(i==5) System.out.print(";"+dataTMP[i][j]);
             }
        }
        dataTMP=jp.procesDWT(dataTMP,  5, true);
        dataTMP=jp.procesDWT(dataTMP,  5,  false);
        //Quantization q=new Quantization();
        //dataTMP=q.quantizy(dataTMP, 40);
        //dataTMP=jp.procesIDWT(dataTMP,  5, false);
        //dataTMP=jp.procesIDWT(dataTMP,  5, true);
        //System.out.println("data:");
        int [] results = new int[w*h];
        offset=1;
        int l;
        int max=Integer.MIN_VALUE;
        int min=Integer.MAX_VALUE;
        for(int i=0; i<h; i++){
            offset=i*w;
             for(int j=0; j<w; j++){
                 l=results[offset+j]=(int)dataTMP[i][j];
                 //if(i==5) System.out.print(";"+dataTMP[i][j]);
                 if(l>max) max=l;
                 if (l<min) min =l;         
             }
        }
        double a = 255.0/(max-min);
        double b= -1*a*min;
        System.out.println("Oto skal:"+a+", "+b);
        for (int i=0; i<results.length; i++){
            l=(int)(a*results[i]+b);
            results[i]=(255 << 24)| (l << 16) |(l << 8) | l;
        }
        mrwPanel.setImage(produceImage(results,w,h));
        rightPanel.validate();
        rightPanel.repaint();
        validate();
        repaint();
    }
    
    public Image produceImage(int [] imageData, int w, int h){
       
       Image img = createImage(new MemoryImageSource(w, h, imageData, 0, w)); 
       
        //tworzony jest obraz w RGB o szeroko�ci w, wysoko�ci h, 
        //na podstawie tablicy pr�bek pix, bez przesuni�cia w tej tablicy z w elementami w linii 
        return img; 
   
    
    }
    
}
