import java.awt.*;
import java.applet.*;
import java.io.*;
import java.util.StringTokenizer;
import java.util.NoSuchElementException ;

public class en_de_cr extends Frame {
    boolean inAnApplet = true;
    Panel cards;
    int result;
    String anyfilename,keyfilename,textfilename,vrmlfilename;
    Label vrmllabel,textlabel,keylabel;
    TextArea statusline;
    TextArea textbox;
File keyfile,textfile,vrmlfile,anyfile;
static String[] vert=new String[256];

create_key kwindow;

String line,tmp;
int[] tpoint=new int[257];
int[] facevert=new int[3];
int vertexnum,code,i,f,flag;
int[] character=new int[257];
Integer[] vertex=new Integer[3];
	MenuBar mb = new MenuBar();
        Menu fm = new Menu("File");
	MenuItem View=new MenuItem("View a textfile");
	MenuItem Encrypt=new MenuItem("Encrypt a file");
	MenuItem Decrypt=new MenuItem("Decrypt a file");
	MenuItem Set_keyfile=new MenuItem("Set keyfile");
	Menu km = new Menu("Keyfile");
	MenuItem CreateKey=new MenuItem("Create a Keyfile");



public en_de_cr(){
vrmllabel=new Label("no vrmlfile set");
textlabel=new Label("no textfile set");
keylabel=new Label("no keyfile set");

textbox=new TextArea("",10,10);
statusline=new TextArea("Status:",5,10);
statusline.setEditable(false);
	Encrypt.disable();
	Decrypt.disable();
        fm.add(Encrypt);
        fm.add(Decrypt);
	fm.add(new MenuItem("-"));
	fm.add(View);
        mb.add(fm);
        km.add(CreateKey);
	km.add(Set_keyfile);
	mb.add(km);
	setMenuBar(mb);

        setLayout(new BorderLayout());	
	Panel tp=new Panel();
	tp.setLayout(new BorderLayout());

//System.out.println("font: "+font);
	tp.add("South",new Label("/ -   Type here the text to be encrypted:   - \\",Label.CENTER));	
	
	add("North",tp);

        Panel cp = new Panel();
        cp.setLayout(new BorderLayout());
        cp.add("North",textbox);
        cp.add("East",new Button("Clear textbox"));
        cp.add("Center",new Button("Encrypt the contents of the textbox"));

        add("Center", cp);
	
	Panel bp=new Panel();
        bp.setLayout(new BorderLayout());
	bp.add("South",statusline);
	
	add("South",bp);
	}


public boolean action(Event event, Object arg) {
String curdir=System.getProperty("user.dir");
//System.out.println(event.target);
File file=new File(curdir);

        if (event.target  instanceof Button) {
		if (((String)arg).equals("Clear textbox")) {
			textbox.setText("");
			}	
	if (((String)arg).equals("Encrypt the contents of the textbox")){
		if(keyfilename!=null){
		cleanup();
		savefile();
		textfilename="boxtextfile.txt";
//		textbox.appendText("\nEncrypt:\ntextfilename:" + textfilename);
				if ((vrmlfilename=fileselector("Select a filename to save resulting vrml-object into","",1))!=null){
//					textbox.appendText("\n vrmlfilename:" + vrmlfilename);
					read_keyfile(keyfilename);
					txt2vrml(keyfilename,textfilename,vrmlfilename);
				}	
				}		
			}
	}

        if (event.target  instanceof MenuItem) {

	if (((String)arg).equals("Create a Keyfile")) {
		statusline.setText("New Create Key");
		if (kwindow == null)
		{
	        	kwindow = new create_key();
			kwindow.inAnApplet = false;
	        	kwindow.setTitle("Cryptogram - key-file creator");
        		kwindow.pack();
		}
        	kwindow.show();
		Encrypt.enable(keyfilename!=null);
		Decrypt.enable(keyfilename!=null); 
		return true;
			}

            if (((String)arg).equals("Decrypt a file")) {
		if ((vrmlfilename=fileselector("Select a wrl-file to Decrypt","",0))!=null){
			cleanup();
				textbox.appendText("\nDecrypt \n vrmlfilename:" + vrmlfilename);
				if ((textfilename=fileselector("Select a filename to save resulting text into","",1))!=null){
					read_keyfile(keyfilename);
//					textbox.appendText("\n textfilename:" + textfilename);
  					vrml2txt(keyfilename,vrmlfilename,textfilename);
					}
			}
		if(statusline.getText()!="Done."){
//			statusline.setText("Error: you must specify a keyfile and a wrl-file to decode, plus a textfilename, to save the result into.");
		    			}
		showfile(textfilename);

            } else if ( ((String)arg).equals("Encrypt a file") ){
		if ((textfilename=fileselector("Select a file to Encrypt","",0))!=null){
			cleanup();
//			textbox.appendText("\nEncrypt:\ntextfilename:" + textfilename);
				if ((vrmlfilename=fileselector("Select a filename to save resulting vrml-object into","",1))!=null){
//					textbox.appendText("\n vrmlfilename:" + vrmlfilename);
					read_keyfile(keyfilename);
					txt2vrml(keyfilename,textfilename,vrmlfilename);
					}
			}
		if(statusline.getText()!="Done."){
//			statusline.setText("Error: you must specify a keyfile and a textfile to encrypt, plus a filename, to save the resulting wrlfile into.");
		    			}

            } else if ( ((String)arg).equals("Set keyfile") ){
		if((keyfilename=fileselector("Select a keyfile for the en/decrypt operations","",0))!=null){
//			textbox.appendText("\nSet keyfilename: " + keyfilename);
			read_keyfile(keyfilename);			
			}
	    } else if ( ((String)arg).equals("View a textfile") ){
			textbox.appendText("view:");
				showfile(fileselector("Select a textfile to view","",0));
		    }
	}
if (keyfilename==null){	Encrypt.disable();
			Decrypt.disable();
			}  
Encrypt.enable(keyfilename!=null);
Decrypt.enable(keyfilename!=null); 
	return true;
    }
void cleanup(){
line=null;
tmp=null;
for (f=0;f<257;f++)tpoint[f]=0;
//int[] tpoint=new int[257];
//int[] facevert=new int[3];
for (f=0;f<3;f++)facevert[f]=0;
vertexnum=0;
code=0;
flag=0;
for (f=0;f<257;f++)character[f]=0;
//int[] character=new int[257];
//Integer[] vertex=new Integer[3];
for (f=0;f<3;f++)vertex[f]=null;
}

void savefile(){
String t=textbox.getText();
//System.out.println(t);
try {
	FileOutputStream boxtextfile = new FileOutputStream("boxtextfile.txt");
	DataOutputStream boxtextdos = new DataOutputStream(boxtextfile);
	boxtextdos.writeBytes(t);
	boxtextdos.writeBytes("\n");
	boxtextdos.close();
		} catch (Exception e) {}
}
    
String fileselector(String title, String subdir,int mode){
String curdir=System.getProperty("user.dir");
      FileDialog fd = new FileDialog(this, title,mode);
// System.out.println(curdir+subdir);
	fd.setDirectory(curdir+subdir);
	fd.show();
//	textbox.appendText("\n" + title + "\n" + fd.getDirectory() + fd.getFile());
	if (fd.getFile()!=null){
	return(fd.getDirectory() + fd.getFile());
	}else return(null);
}

public boolean handleEvent(Event event) {
        if (event.id == Event.WINDOW_DESTROY) {
            if (inAnApplet) {
                dispose();
            } else {
                 System.exit(0);
            }
        }
        return super.handleEvent(event);
    }

public static void main(String args[])
	{
        en_de_cr window = new en_de_cr();
        window.inAnApplet = false;

        window.setTitle("Cryptogram");
        window.pack();
	window.resize(400,370);        
	window.show();
    }



void showfile(String filename){
byte c;
		try {
          FileInputStream anyfile = new FileInputStream(filename);
		DataInputStream dis = new DataInputStream(anyfile);
      while ((line = dis.readLine())!=""){
	textbox.appendText("\n");
	textbox.appendText(line);
    		}
		dis.close();
   		} catch (Exception e) {
 //		     statusline.setText("showfile: "+filename+" is displayed in the textwindow.");
		}

}
/*******************************************************TXT2VRML***************************************************************/
void txt2vrml(String keyfilename,String textfilename,String vrmlfilename)
			{
		set_up_points(textfilename);
/*************************************encrypt********************************************************************/
//        System.out.print("\nWriting the file");
	statusline.appendText("Writing the file\n");
			try {
                FileInputStream textfile = new FileInputStream(textfilename);
				DataInputStream textdis = new DataInputStream(textfile);
                FileOutputStream vrmlfile = new FileOutputStream(vrmlfilename);
				DataOutputStream vrmldos = new DataOutputStream(vrmlfile);
		vrmldos.writeBytes("#VRML V1.0 ascii\n");
		vrmldos.writeBytes("\n");
		vrmldos.writeBytes("Separator { \n");
		vrmldos.writeBytes("\tDirectionalLight{ \n");
		vrmldos.writeBytes("\t \tdirection 0 0 1 \n");
		vrmldos.writeBytes("\t \t \t} \n");
		vrmldos.writeBytes("");
		vrmldos.writeBytes("\n");		    
		vrmldos.writeBytes("PerspectiveCamera { \n");		    
		vrmldos.writeBytes(" \t \tposition 0 3 600 \n");		    
		vrmldos.writeBytes(" \t \torientation 0 0 1 0 \n");		    
		vrmldos.writeBytes(" \t \tfocalDistance 10 \n");		    
		vrmldos.writeBytes(" \t \theightAngle 0.78 \n");	    
		vrmldos.writeBytes(" \t \t} \n");		    
		vrmldos.writeBytes("\n");		    
		vrmldos.writeBytes(" \tSeparator { \n");		    
		vrmldos.writeBytes(" \t \tCoordinate3 { \n");		    
		vrmldos.writeBytes(" \t \t \tpoint [ \n \t \t \t \t");		    
/*****************************************points***********************************************************************/
	       for ( f=0;f<vertexnum ;f++ )
	       {
			if ( f!=0 ) vrmldos.writeBytes(" , \n \t \t \t \t");
		  	vrmldos.writeBytes(vert[tpoint[f]]);
	       }
                 	vrmldos.writeBytes("\n \t \t \t \t]\n");
                        vrmldos.writeBytes("} \n");
                        vrmldos.writeBytes("\n");
/*******************************************facets*********************************************************************/
			vrmldos.writeBytes(" \tIndexedFaceSet {\n");
                        vrmldos.writeBytes(" \t \tcoordIndex [ \n");
//        System.out.print("\nCalculating facets");
	statusline.appendText("Calculating facets\n");
/* first triangle/3 vertex */
	       for ( i=0;i<3 ;i++ )
	       {
                code = textdis.read();
			for ( f=0;f<vertexnum ;f++ )
			{
			if (code==tpoint[f]) facevert[i]=f;
			}
	       }
		vrmldos.writeBytes("\t\t\t\t"+facevert[0]+", "+facevert[1]+", "+facevert[2]+", -1, \n");

/* the rest of the facets */
                while ((code = textdis.read()) != -1){
			facevert[0]=facevert[1];
			facevert[1]=facevert[2];
			for ( f=0;f<vertexnum ;f++ )
			{
                        if (code==tpoint[f]) facevert[2]=f;
			}
                        //System.out.print(".");
			//statusline.appendText(".");
			if ( code!=-1 ) vrmldos.writeBytes("\t\t\t\t"+facevert[0]+", "+facevert[1]+", "+facevert[2]+", -1, \n");
						     }

 		vrmldos.writeBytes("\t\t\t\t]\n");
                vrmldos.writeBytes("\t\t\t}\n");
                vrmldos.writeBytes("\t\t}\n");
                vrmldos.writeBytes("}\n");


				vrmldos.close();
				textdis.close();
//        System.out.print("Done.");
	statusline.setText("Done.\n");
		} catch (Exception e) {
		System.err.println("An error occured during encoding: there is no further error checking, since only a corrupt keyfile can cause errors: \n so please check your input-files, especially the keyfile\n");
                     System.err.println("txt2vrml: Sorry \n" + e);
		     statusline.setText("txt2vrml: " + e);
                 }
       }

/***********************************tpoints***************************************************************************/
		void set_up_points(String textfilename){
			try {
//        System.out.print("\nSetting up vertices");
	statusline.appendText("Setting up vertices...\n");
                FileInputStream textfile = new FileInputStream(textfilename);
				DataInputStream textdis = new DataInputStream(textfile);
vertexnum=0;
                while ((code = textdis.read()) != -1){

		flag=0;
		for(f=0;f<=vertexnum;f++){
					    if ( code!=tpoint[f] ) flag++;
					}
			if ( flag>vertexnum ){
						//System.out.print(".");
						//statusline.appendText(".");
						tpoint[vertexnum]=code;
						vertexnum++;
					     }
						     }
		} catch (Exception e) {
		System.err.println("An error occured during encoding: there is no further error checking, since only a corrupt keyfile can cause errors:\n so please check your input-files, especially the keyfile");
                     System.err.println("txt2vrml.set_up_points: Sorry \n" + e);
                     statusline.setText("txt2vrml.set_up_points: " + e);
                 }
		    	      }



/**************************************set up points from keyfile************************************************************/
		void read_keyfile(String keyfilename){
//        System.out.println("Reading keyfile");
	statusline.appendText("Reading keyfile...\n");
			try {
                     FileInputStream keyfile = new FileInputStream(keyfilename);              
					DataInputStream keydis = new DataInputStream(keyfile);

				for(i=0;i<256;i++)
					{
					//System.out.print(".");
					//statusline.appendText(".");
					vert[i]=keydis.readLine();
					}
					keydis.close();
				} catch (Exception e) {
  	System.err.println("An error occured during reading the keyfile: please check your input data\n");
                     System.err.println("txt2vrml.read_keyfile: Sorry \n" + e);        
  		     statusline.setText("txt2vrml.read_keyfile: " + e + " the keyfile might be corrupt");
                 }
Encrypt.enable(keyfilename!=null);
Decrypt.enable(keyfilename!=null); 
			      }

/***********************************VRML2TXT****************************************************************************************/
void vrml2txt(String keyfilename,String vrmlfilename,String textfilename)
	{

			try {
                FileInputStream vrmlfile = new FileInputStream(vrmlfilename);
				DataInputStream vrmldis = new DataInputStream(vrmlfile);
                FileOutputStream textfile = new FileOutputStream(textfilename);
				DataOutputStream textdos = new DataOutputStream(textfile);
/******************************************seek to vertices**************************************************************/
      while ((line = vrmldis.readLine()).indexOf("point [") != -1){
		}
/*****************************************vertices->used characters in the text*****************************************/
 // System.out.println("\nfinding characters of the text");
  statusline.appendText("finding characters of the text...\n");
      while ((line = vrmldis.readLine()).indexOf("]")==-1)
	    {
        //System.out.print(".");
	//statusline.appendText(".");      	
	    for ( i=0;i<256 ;i++ )
		    {
		        if ( line.indexOf(vert[i])!=-1 )
		        {
			     character[vertexnum]=i;
			     vertexnum++;
			     break;
			}
		    }
	    }
/****************************************skip to facets******************************************************************/
      while ((line = vrmldis.readLine()).indexOf("coordIndex [")==-1)
	    { }
/****************************************order of faces->order of chars->text*******************************************/

/****************************************firt 3 letters******************************************************************/
 // System.out.println("");
// System.out.println("assembling the file");
 statusline.appendText("assembling the file...");
line = vrmldis.readLine();
StringTokenizer st=new StringTokenizer(line,", \t\n\r");
try{
vertex[0]=Integer.valueOf(st.nextToken());
vertex[1]=Integer.valueOf(st.nextToken());
vertex[2]=Integer.valueOf(st.nextToken());
}
catch (NoSuchElementException e){
System.err.println("An error occured while parsing your wrl-file: it is either corrupt or was not created by txt2vrml using your key! \n");
System.err.println("Stringtokenizer: Sorry\n"+e);
    statusline.setText("Stringtokenizer: "+e);
    }

textdos.write(character[vertex[0].intValue()]);
textdos.write(character[vertex[1].intValue()]);
/*****************************************the rest: always vertex[2]*******************************************************/
      while ((line = vrmldis.readLine()).indexOf("]")==-1)
	    {
        //System.out.print(".");
	//statusline.appendText(".");
	textdos.write(character[vertex[2].intValue()]);
        st=new StringTokenizer(line,", \t\n\r");
        try{
            vertex[0]=Integer.valueOf(st.nextToken());
            vertex[1]=Integer.valueOf(st.nextToken());
            vertex[2]=Integer.valueOf(st.nextToken());
            }
            catch (NoSuchElementException e){
System.err.println("An error occured while parsing your wrl-file: it is either corrupt or was not created by txt2vrml using your key! \n");
System.err.println("Stringtokenizer: "+e);
	    	statusline.setText("Stringtokenizer: "+e);
	    	}
	    }
		textdos.writeBytes("\n");
				vrmldis.close();
				textdos.close();

                 }catch (Exception e) {
                     System.err.println("vrml2txt: " + e);
		     statusline.setText("vrml2txt: " + e);
                 }
//        System.out.println("\n Done.");
	statusline.setText("Done.\n");

 }

}


