package ij.plugin;

import ij.*;
import ij.process.*;
import ij.gui.*;
import ij.io.*;

import ij.plugin.PlugIn;
import ij.Stack;

import java.awt.*;
import java.util.*;
import java.io.*;
import java.net.*;

public class stereoTool extends Frame implements PlugIn
{
	ImagePlus sourceImage, bufferImage;
	ImageProcessor ip = null;

	int width, height;
	String title;

	boolean batch=false;
	
	public stereoTool()
	{
		/*MenuBar menuBar = new MenuBar();
		myMenu = new Menu( "File" );
		myMenu.add( new MenuItem( "Exit" ));
		menuBar.add( myMenu );
		setMenuBar( menuBar );*/
		
		SuperCedeConstructor();   // Do not remove this line
		this.show();
			//{{INIT_CONTROLS
		setLayout(null);
		setSize(430,270);
		setTitle("modin's stereoTool");
		//}}
		//{{INIT_MENUS
		//}}
	}

	public void run(String arg) {

		ImagePlus sourceImage = WindowManager.getCurrentImage();
		if (sourceImage==null) {
			hide();
			dispose();
			Info.noImage();
			return;
			//FolderButtonClicked( new Event(folderButton,1,folderButton) );
		}
		if (!batch) {
			this.sourceImage = sourceImage;
				        
       		width  = sourceImage.getWidth();
			height = sourceImage.getHeight();
       	 	title = sourceImage.getTitle();
       	}
	}


	public void update(Graphics g) {
		paint(g);
	}

	public void paint(Graphics g) {
		g.setColor(new Color( 64, 128, 128 ));
		g.fillRect(10,25,310,63);
		g.fillRect(10,93,310,30);
		g.fillRect(10,128,310,30);
	}


	// -------------------------------------------------------------------------------
	// anaglyph2interlaced
	// -------------------------------------------------------------------------------
	protected void A2i_buttonClicked( Event event )
	{	
		bufferImage = new ImagePlus("",sourceImage.getImage(),Info.getImageJ());

		if ( (bufferImage.getType()!=bufferImage.COLOR_256) && (bufferImage.getType()!=bufferImage.COLOR_RGB) ) {
		Info.error("This plug-in requires a color anaglyph image.");
		return;
		}
        else Converter.convertToRGBA(bufferImage);
        
        Stack st = bufferImage.getStack();
		//gets the RED channel
       	byte[] R = (byte[])st.getPixels(1);
		//gets the BLUE or GREEN channel
		int channel = 3;
		if (anatype_choice.getSelectedIndex()==1) channel = 2;
 		byte[] BG = (byte[])st.getPixels(channel);
       	
       	ImagePlus interlacedImage   = NewImage.createByteImage("interlaced-"+title, width, height, 0);
		ImageProcessor interlacedProc = interlacedImage.getProcessor();  
        byte[] interlaced = (byte[])interlacedProc.getPixels();

		// even lines from the red channel, odd lines from the blue/green
		if ( ana_toggle.getState() ) {
        	for (int y=0;y<height;y+=2) {
            	for (int x=0;x<width;x++) {
             		interlaced[y*width + x] = R[y*width + x];
                	interlaced[(y+1)*width + x] = BG[(y+1)*width + x];
           		}
        	}
        }
        // odd lines from the red channel, even lines from the blue/green
        if ( !ana_toggle.getState() ) {
        	for (int y=0;y<height;y+=2) {
            	for (int x=0;x<width;x++) {
             		interlaced[y*width + x] = BG[(y+1)*width + x];
                	interlaced[(y+1)*width + x] = R[y*width + x];
           		}
        	}
        }
       
		// displays the interlaced image    
   		interlacedImage.updateAndDraw();
   		interlacedImage.show();
	}


	// -------------------------------------------------------------------------------
	// pair2anaglyph
	// -------------------------------------------------------------------------------
	protected void P2a_buttonClicked( Event event )
	{		
		bufferImage = new ImagePlus("",sourceImage.getImage(),Info.getImageJ());
        ip = bufferImage.getProcessor();

		ij.Converter.convertToGrayscale(bufferImage);
		ImageProcessor ip = bufferImage.getProcessor();
        byte[] buffer = (byte[])ip.getPixels();
        
        ImagePlus anaglyphImage   = NewImage.createRGBImage("anaglyph-"+title, width/2, height, 0);
		ImageProcessor anaglyphProc = anaglyphImage.getProcessor();
        int[] anaglyph = (int[])anaglyphProc.getPixels();

		int r=0;
		int g=0;
		int b=0;
		
		// *** red-blue anaglyph ***
		if (anatype_choice.getSelectedIndex()==0) {
			//copies the right picture into the red channel, left to the blue
			if ( !ana_toggle.getState() ) {
        		for (int y=0;y<height;y++) {
            		for (int x=0;x<width/2;x++) {
               			r = 0xff & buffer[y*width + x];
			   			b = 0xff & buffer[y*width + x + width/2];			   	
		       			anaglyph[y*width/2+x] = 0xff000000 | (r<<16) | b;
            		}
          		} 
        	} 
        	//copies the left picture into the red channel, right to the blue
        	if ( ana_toggle.getState() ) {
        		for (int y=0;y<height;y++) {
            		for (int x=0;x<width/2;x++) {
               			b = 0xff & buffer[y*width + x];
			   			r = 0xff & buffer[y*width + x + width/2];			   	
		       			anaglyph[y*width/2+x] = 0xff000000 | (r<<16) | b;
		    		}
          		} 
        	}
        }
		// *** red-green anaglyphs ***
        if (anatype_choice.getSelectedIndex()==1) {
        	//copies the right picture into the red channel, left to the green
        	if ( !ana_toggle.getState() ) {
        		for (int y=0;y<height;y++) {
           			for (int x=0;x<width/2;x++) {
                		r = 0xff & buffer[y*width + x];
			    		g = 0xff & buffer[y*width + x + width/2];
			       		anaglyph[y*width/2+x] = 0xff000000 | (r<<16) | (g<<8);           
            		}
          		}
        	}
        	//copies the left picture into the red channel, right to the green
       		if ( ana_toggle.getState() ) {
        		for (int y=0;y<height;y++) {
           			for (int x=0;x<width/2;x++) {
                		g = 0xff & buffer[y*width + x];
			    		r = 0xff & buffer[y*width + x + width/2];
			        	anaglyph[y*width/2+x] = 0xff000000 | (r<<16) | (g<<8);           
            		}
          		}
        	}
        }
        
		// displays the anaglyph image    
		anaglyphImage.updateAndDraw();
		anaglyphImage.show();
	}

	// -------------------------------------------------------------------------------
	// pair2interlaced
	// -------------------------------------------------------------------------------
	protected void P2i_buttonClicked( Event event )
	{
		bufferImage = new ImagePlus("",sourceImage.getImage(),Info.getImageJ());
        ip = bufferImage.getProcessor();

        // COLOR_RGB conversion for COLOR_256pictures
        if (bufferImage.getType()==bufferImage.COLOR_256) {
            Converter.convertToRGB(bufferImage);
            ip = bufferImage.getProcessor();
        }

        //COLOR_RGB conversion for RGBA pictures
        if (bufferImage.getType()==bufferImage.RGBA)  {
            //Converter.convertRGBAtoRGB(bufferImage);
            Converter.convertToRGB(bufferImage);
            ip = bufferImage.getProcessor();
        }

        // GRAY8 conversion for GRAY16 and GRAY32 pictures
        if ( (bufferImage.getType()==bufferImage.GRAY16) || (bufferImage.getType()==bufferImage.GRAY32) ) {
            Converter.convertToGrayscale(bufferImage);
            ip = bufferImage.getProcessor();
        }

        // part for GRAY8 pictures
        if ( bufferImage.getType()==bufferImage.GRAY8) {
            
            byte[] pixels = (byte[])ip.getPixels();
            
            // creates a new image
            ImagePlus interlacedImage   = NewImage.createByteImage("interlaced-"+title, width/2, height, 0);
		    ImageProcessor interlacedProc = interlacedImage.getProcessor();  
           	byte[] interlaced = (byte[])interlacedProc.getPixels();

			if ( int_toggle.getState() ) {
            //writes the even lines from the left picture and odd lines from the right one
            for (int y=0;y<height;y+=2) {
                for (int x=0;x<width/2;x++) {
                      interlaced[y*width/2 + x] = pixels[y*width + x];
                      interlaced[(y+1)*width/2 + x] = pixels[(y+1)*width + x + width/2];
                }
            } }
            if ( !int_toggle.getState() ) {
            //writes the even lines from the right picture and odd lines from the left one
         	for (int y=0;y<height;y+=2) {
                for (int x=0;x<width/2;x++) {
                      interlaced[y*width/2 + x] = pixels[(y+1)*width + x + width/2];
                      interlaced[(y+1)*width/2 + x] = pixels[y*width + x]; 
                }
            } }

            // displays the interlaced image    
   		    interlacedImage.updateAndDraw();
   		    interlacedImage.show();
   		    }
        
        
        // part for COLOR_RGB pictures
        if (bufferImage.getType()==bufferImage.COLOR_RGB) {
              
            int[] pixels = (int[])ip.getPixels();
            
            // creates a new image
            ImagePlus interlacedImage   = NewImage.createRGBImage("interlaced-"+title, width/2, height, 0);
		    ImageProcessor interlacedProc = interlacedImage.getProcessor();
           	int[] interlaced = (int[])interlacedProc.getPixels();

			if ( int_toggle.getState() ) {
            //writes the even lines from the left picture and odd lines from the right one
            for (int y=0;y<height;y+=2) {
                for (int x=0;x<width/2;x++) {
                      interlaced[y*width/2 + x] = pixels[y*width + x];
                      interlaced[(y+1)*width/2 + x] = pixels[(y+1)*width + x + width/2];
                }
            } }
            else {
            //writes the even lines from the right picture and odd lines from the left one
         	for (int y=0;y<height;y+=2) {
                for (int x=0;x<width/2;x++) {
                      interlaced[y*width/2 + x] = pixels[(y+1)*width + x + width/2];
                      interlaced[(y+1)*width/2 + x] = pixels[y*width + x]; 
                }
            } }
            
            // displays the interlaced image    
   		    interlacedImage.updateAndDraw();
   		    interlacedImage.show();
    	}
      
	}

	// -------------------------------------------------------------------------------
	// anaglyph2anaglyph
	// -------------------------------------------------------------------------------
	protected void A2a_buttonClicked( Event event )
	{
		bufferImage = new ImagePlus("",sourceImage.getImage(),Info.getImageJ());

		if ( (bufferImage.getType()!=bufferImage.COLOR_256) && (bufferImage.getType()!=bufferImage.COLOR_RGB) ) {
		Info.error("This plug-in requires a color anaglyph image.");
		return;
		}
        else Converter.convertToRGBA(bufferImage);
       	
       	Stack st = bufferImage.getStack();
		//gets the RED, GREEN and BLUE channel
       	byte[] R = (byte[])st.getPixels(1);
 		byte[] G = (byte[])st.getPixels(2);
 		byte[] B = (byte[])st.getPixels(3);

       	ImagePlus anaglyphImage   = NewImage.createRGBImage("anaglyph-"+title, width, height, 0);
		ImageProcessor anaglyphProc = anaglyphImage.getProcessor();  
        int[] anaglyph = (int[])anaglyphProc.getPixels();
		
       	byte[] aR = new byte[width*height];
 		byte[] aG = new byte[width*height];
 		byte[] aB = new byte[width*height];
        
        // *** conversion from red-green to red-blue anaglyph ***
		if (anatype_choice.getSelectedIndex()==0) {
			//copies the green channel into the blue, doesn't change red
			if ( !ana_toggle.getState() ) {
  				aR = R;
  				aG = B;
  				aB = G;
        	} 
			//copies the green channel into the red, the red into blue
        	if ( ana_toggle.getState() ) {
  				aR = G;
  				aG = B;
  				aB = R;
        	}
        }

        // *** conversion from red-blue to red-green anaglyph ***
		if (anatype_choice.getSelectedIndex()==1) {
			//copies the blue channel into the green, doesn't change red
			if ( !ana_toggle.getState() ) {
 				aR = R;
  				aG = B;
  				aB = G;
        	} 
			//copies the blue channel into the red, the red into green
        	if ( ana_toggle.getState() ) {
         		aR = B;
        		aB = G;
        		aG = R;
        	}
        }
        
        int r=0;
		int g=0;
		int b=0;
		
        for (int i=0;i<width*height;i++) {
               	r = 0xff & aR[i];
               	g = 0xff & aG[i];
			   	b = 0xff & aB[i];			   	
		       	anaglyph[i] = 0xff000000 | (r<<16) | (g<<8) | b;
        } 

		// displays the anaglyph image    
		anaglyphImage.updateAndDraw();
		anaglyphImage.show();
	}

	protected void Exit_buttonClicked( Event event )
	{
		if (!batch)
			sourceImage.unreserve(); 
		this.hide();
		this.dispose();
	}

	protected void FolderButtonClicked( Event event )
	{
		FileDialog fd = new FileDialog(this, "Open Batch Directory...");
		fd.show();
		//String fileName = fd.getFile();
		String directory = fd.getDirectory();
		folderLabel.setText(directory);
		fd.dispose();
		
		batch=true;
	}

	public boolean handleEvent( Event event )
	{
		// 	Tests for custom events go here...

		return SuperCedeEvent( event );   // Do not remove this line
	}

	protected void selectedExit()
	{
		if (!batch)
			sourceImage.unreserve(); 
		this.hide();
		this.dispose();
	}

	public boolean action( Event event, Object arg )
	{
		if (event.target instanceof MenuItem)
		{
			String label = (String) arg;
			if (label.equalsIgnoreCase( "Exit" ))
			{
				selectedExit();
				return true;
			}
		}
		return super.action( event, arg );
	}

	/*public static void main( String args[] )
	{
		// 	You can add code anywhere in this method.

		stereoTool app = new stereoTool();
		app.show();
	}*/

	// SuperCede Begin Methods
	// 		Do not remove the Begin and End markers.
	// 		The editor will rewrite the contents of this section each time the form is saved.
	private final void SuperCedeConstructor()
	{
		setTitle( "modin's stereoTool v0.9" );
		setResizable( false );
		setCursor( Frame.DEFAULT_CURSOR );
		setLayout( null );
		setForeground( new Color( 0, 0, 0 ));
		setBackground( new Color( 192, 192, 192 ));
		addNotify();
		resize( (insets().left + insets().right + 320), (insets().top + insets().bottom + 225) );

		a2i_button = new Button( "ana2interlaced" );
		a2i_button.setFont( new Font( "Helvetica", Font.BOLD, 12 ));
		add( a2i_button );
		a2i_button.reshape( (insets().left + 10), (insets().top + 10), 100, 20 );

		p2a_button = new Button( "pair2ana" );
		p2a_button.setFont( new Font( "Helvetica", Font.BOLD, 12 ));
		add( p2a_button );
		p2a_button.reshape( (insets().left + 110), (insets().top + 10), 100, 20 );

		anatype_choice = new Choice();
		anatype_choice.addItem( "red/blue" );
		anatype_choice.addItem( "red/green" );
		anatype_choice.setBackground( new Color( 255, 255, 255 ));
		add( anatype_choice );
		anatype_choice.reshape( (insets().left + 10), (insets().top + 35), 100, 21 );

		anacolor_choice = new Choice();
		anacolor_choice.addItem( "monochrome" );
		anacolor_choice.addItem( "color" );
		anacolor_choice.setBackground( new Color( 255, 255, 255 ));
		anacolor_choice.disable();
		add( anacolor_choice );
		anacolor_choice.reshape( (insets().left + 110), (insets().top + 35), 100, 21 );

		ana_toggle = new Checkbox( "toggle" );
		ana_toggle.setForeground( new Color( 255, 255, 255 ));
		ana_toggle.setBackground( new Color( 64, 128, 128 ));
		add( ana_toggle );
		ana_toggle.reshape( (insets().left + 230), (insets().top + 35), 80, 20 );

		p2i_button = new Button( "pair2interlaced" );
		p2i_button.setFont( new Font( "Helvetica", Font.BOLD, 12 ));
		add( p2i_button );
		p2i_button.reshape( (insets().left + 10), (insets().top + 75), 100, 20 );

		int_toggle = new Checkbox( "toggle" );
		int_toggle.setForeground( new Color( 255, 255, 255 ));
		int_toggle.setBackground( new Color( 64, 128, 128 ));
		add( int_toggle );
		int_toggle.reshape( (insets().left + 230), (insets().top + 75), 80, 20 );

		infoLabel = new Label( "stereoTool v1.0", Label.LEFT );
		infoLabel.setFont( new Font( "Helvetica", Font.PLAIN, 9 ));
		add( infoLabel );
		infoLabel.reshape( (insets().left + 10), (insets().top + 200), 70, 10 );

		label1 = new Label( "(c) 1998 by Martin Kaltenbrunner", Label.LEFT );
		label1.setFont( new Font( "Helvetica", Font.PLAIN, 9 ));
		add( label1 );
		label1.reshape( (insets().left + 10), (insets().top + 210), 150, 10 );

		exit_button = new Button( "EXIT" );
		exit_button.setFont( new Font( "Helvetica", Font.BOLD, 10 ));
		add( exit_button );
		exit_button.reshape( (insets().left + 260), (insets().top + 200), 50, 20 );

		a2a_button = new Button( "ana2ana" );
		a2a_button.setFont( new Font( "Helvetica", Font.BOLD, 12 ));
		add( a2a_button );
		a2a_button.reshape( (insets().left + 210), (insets().top + 10), 100, 20 );

		//folderButton = new Button( "select folder" );
		//folderButton.setFont( new Font( "Helvetica", Font.BOLD, 12 ));
		//add( folderButton );
		//folderButton.reshape( (insets().left + 10), (insets().top + 110), 100, 20 );

		//folderLabel = new Label( "<none selected>", Label.CENTER );
		//folderLabel.setForeground( new Color( 255, 255, 255 ));
		//folderLabel.setBackground( new Color( 0, 128, 128 ));
		//add( folderLabel );
		//folderLabel.reshape( (insets().left + 120), (insets().top + 110), 190, 20 );

	}

	private final boolean SuperCedeEvent( Event event )
	{
		if ((event.target == this) && (event.id == Event.WINDOW_DESTROY))
		{
			selectedExit();
			return true;
		}
		if ((event.target == a2i_button) && (event.id == Event.ACTION_EVENT))
		{
			A2i_buttonClicked( event );
			return true;
		}
		if ((event.target == p2a_button) && (event.id == Event.ACTION_EVENT))
		{
			P2a_buttonClicked( event );
			return true;
		}
		if ((event.target == p2i_button) && (event.id == Event.ACTION_EVENT))
		{
			P2i_buttonClicked( event );
			return true;
		}
		if ((event.target == exit_button) && (event.id == Event.ACTION_EVENT))
		{
			Exit_buttonClicked( event );
			return true;
		}
		if ((event.target == a2a_button) && (event.id == Event.ACTION_EVENT))
		{
			A2a_buttonClicked( event );
			return true;
		}
		if ((event.target == folderButton) && (event.id == Event.ACTION_EVENT))
		{
			FolderButtonClicked( event );
			return true;
		}
		return super.handleEvent( event );
	}

	private final void SuperCedeStart()
	{
	}

	private final void SuperCedeStop()
	{
	}
	// SuperCede End Methods

	//Menu myMenu;

	// SuperCede Begin Declarations
	// 		Do not remove the Begin and End markers.
	// 		The editor will rewrite the contents of this section each time the form is saved.
	Button a2i_button;
	Button p2a_button;
	Choice anatype_choice;
	Choice anacolor_choice;
	Checkbox ana_toggle;
	Button p2i_button;
	Checkbox int_toggle;
	Label infoLabel;
	Label label1;
	Button exit_button;
	Button a2a_button;
	Button folderButton;
	Label folderLabel;
	// SuperCede End Declarations
	//{{DECLARE_CONTROLS
	//}}
	//{{DECLARE_MENUS
	//}}
}


// SuperCede Begin Form Properties
// 3
// 1 2 "modin's stereoTool v1.0" 100000 0 400 0 F F F "Dialog"
// 320 225 13238272 0 2147483666 2147483663
// 0 0 1 1 0 "stereoTool" 0 0 0 2 2 0 T T F T F
// ""
// F F F F F F F F F F F F F
// 13
// Button 10 110 10 30
//  A 1 "ana2interlaced" T 3 "a2i_button" 2 100 20 4 T T T 1 0 16777215  "Helvetica" 120000 0 700 0 F F F F F F F F F F F F F -1 -1 1 1 F F 0 0 0 0 0 0 0 0 0 "" T
// Button 110 210 10 30
//  A 2 "pair2ana" T 3 "p2a_button" 2 100 20 4 T T T 1 0 16777215  "Helvetica" 120000 0 700 0 F F F F F F F F F F F F F -1 -1 1 1 F F 0 0 0 0 0 0 0 0 0 "" T
// Choice 10 110 35 56
//  A 3 "red/blue|red/green|" F A "" "" "" "" "" 3 "anatype_choice" 2 100 21 4 T T T 0 0 16777215  "Dialog" 100000 0 400 0 F F F F F F F F F F F F F -1 -1 1 1 F F 0 0 0 0 0 0 0 0 0 "" F
// Choice 110 210 35 56
//  A 4 "monochrome|color|" F A "" "" "" "" "" 3 "anacolor_choice" 2 100 21 4 T F T 0 0 16777215  "Dialog" 100000 0 400 0 F F F F F F F F F F F F F -1 -1 1 1 F F 0 0 0 0 0 0 0 0 0 "" F
// Checkbox 230 310 35 55
//  A 5 "toggle" F F A "" "" 3 "ana_toggle" 2 80 20 4 T T F 0 16777215 8421440  "Dialog" 100000 0 400 0 F F F F F F F F F F F F F -1 -1 1 1 F F 0 0 0 0 0 0 0 0 0 "" F
// Button 10 110 75 95
//  A 6 "pair2interlaced" T 3 "p2i_button" 2 100 20 4 T T T 1 0 16777215  "Helvetica" 120000 0 700 0 F F F F F F F F F F F F F -1 -1 1 1 F F 0 0 0 0 0 0 0 0 0 "" T
// Checkbox 230 310 75 95
//  A 7 "toggle" F F A "" "" 3 "int_toggle" 2 80 20 4 T T F 0 16777215 8421440  "Dialog" 100000 0 400 0 F F F F F F F F F F F F F -1 -1 1 1 F F 0 0 0 0 0 0 0 0 0 "" F
// Label 10 80 200 210
//  A 8 "stereoTool v1.0" 0 3 "infoLabel" 2 70 10 4 T T T 1 0 16777215  "Helvetica" 90000 0 400 0 F F F F F F F F F F F F F -1 -1 1 1 F F 0 0 0 0 0 0 0 0 0 "" T
// Label 10 160 210 220
//  A 9 "(c) 1998 by Martin Kaltenbrunner" 0 3 "label1" 2 150 10 4 T T T 1 0 16777215  "Helvetica" 90000 0 400 0 F F F F F F F F F F F F F -1 -1 1 1 F F 0 0 0 0 0 0 0 0 0 "" T
// Button 260 310 200 220
//  A 10 "EXIT" T 3 "exit_button" 2 50 20 4 T T T 1 0 16777215  "Helvetica" 100000 0 700 0 F F F F F F F F F F F F F -1 -1 1 1 F F 0 0 0 0 0 0 0 0 0 "" T
// Button 210 310 10 30
//  A 11 "ana2ana" T 3 "a2a_button" 2 100 20 4 T T T 1 0 16777215  "Helvetica" 120000 0 700 0 F F F F F F F F F F F F F -1 -1 1 1 F F 0 0 0 0 0 0 0 0 0 "" T
// Button 10 110 110 130
//  A 12 "select folder" T 3 "folderButton" 2 100 20 4 T T T 1 0 16777215  "Helvetica" 120000 0 700 0 F F F F F F F F F F F F F -1 -1 1 1 F F 0 0 0 0 0 0 0 0 0 "" T
// Label 120 310 110 130
//  A 13 "<none selected>" 1 3 "folderLabel" 2 190 20 4 T T F 0 16777215 8421376  "Dialog" 100000 0 400 0 F F F F F F F F F F F F F -1 -1 1 1 F F 0 0 0 0 0 0 0 0 0 "" F
// 13 0 1 2 3 4 5 6 7 8 9 10 11 12
// SuperCede End Form Properties
// SuperCede Begin Editor Properties
// 1
// 3 813 0 T 3 8388736 8421440 T T F T T F T 0 0 0 0
// 0 16777215
// 0
// 0
// SuperCede End Editor Properties
