import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.net.URL;
import javax.swing.*;
import javax.sound.sampled.*;
import java.util.*;
import java.applet.*; 
//import parport.ParallelPort;
class Fio 
 {
  private static final Component comp = new Component() {};
  private static final MediaTracker tracker = new MediaTracker(comp);
  boolean deb=false;
  M parent;
  //Img img;
  URL filescodebase;
  URL url;
  Hashtable diah,fish,doah,fosh;
  String resavename;
  //ParallelPort lpt1;
  public Fio(M p)
   {
    parent=p;
    filescodebase=parent.filescodebase;
    //  filescodebase="C:/webroot/ajlogo/html/ajlogo/version3beta/";
    doah=new Hashtable();
    fosh=new Hashtable();
    diah=new Hashtable();
    fish=new Hashtable();
    resavename="";
    //lpt1 = new parport.ParallelPort(0x378);
   }
  String pwd()
   {
    File f=new File(".");
    String s=f.getAbsolutePath();
    return s.substring(0,s.length()-2);
   }
  void delete(String fn)
   {
    File f=new File(fn);
    tta("result:"+f.getPath());
    tta("result:"+f.delete());
   }
  void gurli(String s)
   {
    InputStream mis;
    try { url=new URL(s); }
    catch (Exception e)
     {
      tta("URL "+url+" failed, reason is:"+ e.toString());
      return;
     }
    try { mis=url.openStream(); }
    catch (Exception e)
     {
      tta("URL "+url+" failed, reason is:"+ e.toString());
      return;
     }
    DataInputStream dis=new DataInputStream(mis);
   }
  String getURL(String s)
   {
    InputStream myurlstream;
    String ziy="",htmlstr="";
    try { url=new URL(s); }
    catch (Exception e)
     {
      tta("URL "+url+" failed, reason is:"+ e.toString());
      return "";
     }
    try { myurlstream =url.openStream(); }
    catch (Exception e)
     {
      tta("URL "+url+" failed, reason is:"+ e.toString());
      return "";
     }
    DataInputStream dis=new DataInputStream(myurlstream);
    try
     {
      ziy= dis.readLine();
     }
    catch( IOException e) { }
    while (ziy != null)
     {
      htmlstr +=ziy;
      try { ziy = dis.readLine(); }
      catch( IOException e) { }
     }
    return htmlstr;
   }
  public AudioClip getAC(String s)
   {
    String fn=s;
    if(fn.indexOf(".wav") == -1) fn=fn+".wav";
    if(fn.indexOf("audio/")== -1) fn="audio/"+fn;
    return realgetAC(fn);
   }
  AudioClip realgetAC(String s)
   {
    return realgetAC(filescodebase,s);
   }
  AudioClip realgetAC(URL codebase,String s)
   {
    AudioClip ac=null;
    //tta("realgetAC codebase:"+codebase+" s:"+s);
    if(parent.isApplet) return  parent.ajlogo.getAudioClip(codebase,s);
    else if(codebase==null)
     {
      //try { url=new URL("file:///home/arniemon/public_html/ajlogo/version3beta/"+s); }
      //catch (MalformedURLException e){ tta("Malformed url"); }
      //  save("C:/webroot/ajlogo/html/ajlogo/version3beta/audio/fixed.wav");
      //try { url=new URL("file:///C:/webroot/ajlogo/html/ajlogo/version3beta/audio/"+s);}
      try { url=new URL("file:///webroot/ajlogo/html/ajlogo/version3beta/"+s); }
      catch (MalformedURLException e){ tta("Malformed url"); }
      //tta("codebase is null - realgetClip url:"+url);
      ac=Applet.newAudioClip(url);
      if(ac==null) tta("realget AC is null");
      //else tta("Good   realgetAC is not null");
      return ac;
     }
    else 
     {
      try { url=new URL(codebase,s); }
      catch (MalformedURLException e){ tta("Malformed url"); }
      //tta("codebase is not null - realgetClip url:"+url);
      ac=Applet.newAudioClip(url);
      if(ac==null) tta("realget AC is null");
      //else tta("realgetAC is not null");
      return ac;
     }
   }
  AudioInputStream loadAIS(String fn)
   {
    if(fn.indexOf("/")== -1) fn="audio/"+fn;
    AudioInputStream ais;
    try { ais=AudioSystem.getAudioInputStream(new File(fn)); }
    catch (Exception ex) { return null; }
    return ais;
   }
  Clip getClip(String fn)
   {
    Clip clip=null;
    AudioInputStream ais=loadAIS(fn);
    try
     {
      DataLine.Info info = new DataLine.Info(Clip.class,ais.getFormat());
      clip = (Clip) AudioSystem.getLine(info);
      clip.open(ais);
     }
    catch (LineUnavailableException e) { }
    catch (IOException e) { }
    finally 
     {
      try
       {
        ais.close();
       }
      catch (IOException e) { }
     }
    return clip;
   }
  String lMod(String fn)
   {
    if(fn.indexOf(".model") == -1) fn=fn+".model";
    if(fn.indexOf("/")== -1) fn="models/"+fn;
    return realload(fn,false,false);
   }
  public String load(String s,boolean loud) { return load(s,false,loud); }
  String load(String s,boolean b,boolean loud)
   {
    String fn=s;
    if(fn.indexOf(".logo") == -1) fn=fn+".logo";
    resavename=fn;
    if(fn.indexOf("logoprogs/")== -1) fn="logoprogs/"+fn;
    return realload(fn,b,loud);
   }
  String realload(String fn,boolean b,boolean loud)
   {
    return realload(filescodebase,fn,b,loud);
   }
  String realload(URL codebase,String fn,boolean b,boolean loud)
   {
    //tta("realload codebase:"+codebase+" fn:"+fn);
    String sb="";
    if(codebase==null)
     {
      FileInputStream fis;
      try { fis = new FileInputStream(fn); }
      catch( IOException e)
       {
        tta("Loading error for:"+fn);
        return "";
       }
      return readFile(new DataInputStream(fis),b,loud);
     }
    else
     {
      try { url = new URL(codebase, fn); }
      catch(MalformedURLException e) { tta("was malformed:"+fn); }
      // tta("url:"+url);
      return readFile(openURL(url),b,loud);
     }
   }
  public String readFile(DataInput dia,boolean b,boolean loud)
   {
    //tta("readFile");
    if(dia == null) 
     {
      tta ("DataInput is null in readFile; Load error");
      return "";
     }
    //tta("dia not null");
    String sa="";
    try { sa=dia.readLine(); }
    catch( IOException e) 
     {
      tta("readLine in readFile; Load error");
      return "";
     }
    if(loud) ttancr("Loading..");
    String sb="";
    boolean ftt=true;
    while(sa != null)
     {
      if(loud) ttancr(".");
      if(b) sb +=sa+"\n";
      else if(ftt)
       {
        ftt=false;
        sb =sa;
       }
      else sb +=" "+sa;
      try { sa = dia.readLine(); }
      catch( IOException e) { return "error with readFile readLine sb:"+sb+" sa:"+sa; }
      catch(NullPointerException e) { return "error with readFile null pointer"; }
     }
    if(loud) ttace(" done");
    return sb;
   }
  String[] loadSa(String fn)
   {
    //  tta("Fio.loadSa fn:"+fn);
    URL fileURL=null;
    DataInput dia;
    ArrayList<String> als = new ArrayList<String>();
    String[] sa=new String[0];
    try
     {
      if(fn.indexOf("webroot")>-1)
       {
        fileURL=new URL("file:///"+fn); 
       }
      else  fileURL=new URL("file:///webroot/ajlogo/html/ajlogo/version3beta/"+fn); 
      //tta("Fio.loadSa fileURL:"+fileURL);
      dia=openURL(fileURL);
     }
    catch(MalformedURLException e)
     {
      tta("fileURL is malformed:"+fileURL);
      return null;
     }
    int i=1;
    String rl="not null";
    while(rl != null)
     {
      try 
       {
        rl=dia.readLine();
        //tta("Fio.loadSa rl:"+rl);
        if(rl != null && rl != "")
         {
          als.add(rl);
         }
       }
      catch( IOException e) 
       { 
        tta("Fio.loadSa IOException");
        rl=null;
       }
      catch(NullPointerException e) 
       { 
        tta("Fio.loadSa null pointer exception"); 
        rl=null;
       }
     }
    sa=new String[als.size()];
    als.toArray(sa); 
    tta("Fio.loadSa fileURL:"+fileURL+" sa.length:"+sa.length);
    return sa;
   }
  public void sMod(String fn,String sc)
   {
    //tta("fn:"+fn+" sc:"+sc);
    if(fn.indexOf(".model") == -1) fn=fn+".model";
    if(fn.indexOf("/")== -1) fn="models/"+fn;
    realsave(fn,sc);
   }
  public void savechat(String fn,String sc)
   {
    if(fn.indexOf(".txt") == -1) fn=fn+".txt";
    if(fn.indexOf("/")== -1) fn="chatsessions/"+fn;
    realsave(fn,sc);
   }
  public void save(String fn,String sc)
   {
    if(fn.equals(""))
     {
      if(resavename.equals(""))
       {
        tta("On new programs, use save first");
        tta("Will save as 'temp' for now");
        fn="temp";
       }
      else
       {
        savelib(resavename,sc);
        tta(resavename+" is resaved");
        return;
       }
     }
    savelib(fn,sc);
    resavename=fn;
    tta(fn+" is saved");
   }
  void savelib(String fn,String sc)
   {
    if(fn.indexOf(".logo") == -1) fn=fn+".logo";
    if(fn.indexOf("/")== -1) fn="logoprogs/"+fn;
    realsave(fn,sc);
   }
  void realsave(String fn,String sc)
   {
    // fn="C:/webroot/ajlogo/html/ajlogo/version3beta/"+fn;
    fn="/webroot/ajlogo/html/ajlogo/version3beta/"+fn;
    tta("realsave fn:"+fn+":   sc:"+sc+":");
    try 
     {
      FileOutputStream fos=new FileOutputStream(fn);
      writeBytes(new DataOutputStream(fos),sc); 
      //fos.close();
     }
    catch( IOException e) { tta("File save error\nfile:"+fn); }
   }
  public void writeBytes(String fh,String sc)
   {
    writeBytes((DataOutput)doah.get(fh),sc);
   }
  public void writeBytes(DataOutput doa,String sc)
   {
    try { doa.writeBytes(sc); }
    catch( IOException e) { }
   }
  void oldwfba(String fn,byte[] a) throws Exception
   {
    FileOutputStream fos=new FileOutputStream(fn);
    DataOutputStream dos=new DataOutputStream(fos);
    dos.write(a);
    dos.flush();
    dos.close();
    fos.close();
   }
  void wfba(String fn,byte[] a) throws Exception
   {
    long length=a.length;
    tta("Fio.wfba fn:"+fn+" bytearray length:"+length);
    FileOutputStream fos=new FileOutputStream(fn);
    DataOutputStream dos=new DataOutputStream(fos);
    int offset=0;
    int bufflength=1024*1024;
    tta("Fio.wfba  offset:"+offset+" bufflength:"+bufflength);
    if(offset+bufflength> length) 
     {
      bufflength=(int)(length-offset);
      tta("Fio.wfba changed bufflength:"+bufflength);
     }
    while(bufflength>0)
     {
      dos.write(a,offset,bufflength);
      tta("Fio write offset:"+offset+" bufflength:"+bufflength);
      offset+=bufflength;
      if(offset+bufflength> length)
       {
        bufflength=(int)(length-offset);
        tta("Fio.wfba soon last offset:"+offset+" bufflength:"+bufflength);
       }
     }
    tta("Fio.wfba post while");
    dos.flush();
    dos.close();
    fos.close();
    tta("Fio.wfba post close");
   }
  void writebytefile(String fn,byte[] byarray)
   {
    wopen("temp",fn);
    boolean cont=true;
    DataOutput doa=(DataOutput)doah.get("temp");
    int t=0;
    if(byarray == null)
     {
      tta("byarray is null");
      return;
     }
    while(cont && t<byarray.length)
     {
      try { doa.writeByte(byarray[t]); }
      catch( IOException e) { cont=false; }
      t++;
     }
   }
  void writefile(String fn,byte[] bya,short[] sa,short[] sb)
   {
    wopen("temp",fn);
    boolean cont=true;
    byte b1=0x00;
    DataOutput doa=(DataOutput)doah.get("temp");
    int t=0;
    if(bya == null) tta("byte array is null");
    else
     {
      try
       {
        while(cont && t<bya.length)
         {
          doa.writeByte(bya[t]);
          t++;
         }
       }
      catch( IOException e) { cont=false; }
     }
    cont=true;
    t=0;
    try 
     {
      while(cont && t<sa.length)
       {
        doa.writeByte((byte)(0x00ff & sa[t]));
        doa.writeByte((byte)((0xff00 & sa[t]) >>8));
        doa.writeByte((byte)(0x00ff & sb[t]));
        doa.writeByte((byte)((0xff00 & sb[t]) >>8));
        t++;
       }
     }
    catch( IOException e) { cont=false; }
   }
  public void writeByte(String fh,double d)
   {
    writeByte((DataOutput)doah.get(fh),(byte)d);
   }
  public void writeByte(DataOutput doa,byte byt)
   {
    try { doa.writeByte(byt); }
    catch( IOException e) { }
   }
  public void ropen(String h,String n)
   {
    String fh=h;
    String fn=n;
    // fn=filescodebase+fn;
    //  File file=new File(fn);
    FileInputStream fis=null;
    try { fis = new FileInputStream(fn); }
    catch( IOException e)
     {
      // tta("filescodebase:"+filescodebase);
      //  tta("error with file:"+fn+":   FileInputStream("+fn+")"); //)
     }
    DataInput dia = new DataInputStream(fis);
    fish.put(fh,fis);
    diah.put(fh,dia);
   }
  byte[] readByteArrayFile(String f)
   {
    tta("rBAF for String:"+f);
    return readByteArrayFile(f,Integer.MAX_VALUE); 
   }
  byte[] readByteArrayFile(String f,long maxlength)
   {
    tta("rBAF for String and long:"+f+"  "+maxlength);
    tta("filescodebase:"+filescodebase);
    String forurl="";
    if(f.indexOf("http")> 0) forurl=f;
    else if(filescodebase==null)
     {
      if(f.indexOf("/") ==0)
       {
        forurl="file://"+f;
       }
      else
       {
        // good w  forurl="C:/webroot/ajlogo/html/ajlogo/version3beta/"+f;
        forurl="file:///webroot/ajlogo/html/ajlogo/version3beta/"+f;
       }
     }
    else
     {
      if(f.indexOf("/")==0)
       {
        forurl="file://"+f;
       }
      else
       {
        forurl=filescodebase+f;
       }
     }
    try
     {
      //if(parent.isApplet && forurl.equals("")) forurl=filescodebase+f;
      URL lurl=new URL(forurl);
      //tta("rBAF for String and long f:"+f+" fn:"+fn+"  "+maxlength+"  lurl:"+lurl);
      tta("rBAF for String and long f:"+f+" maxlength: "+maxlength+"  lurl:"+lurl);
      return readByteArrayFile(lurl,Integer.MAX_VALUE);
     }
    catch (MalformedURLException e)
     {
      tta("readByteArrayFile for String and long -- Error with lurl for f:"+f+"  reason is:"+ e.toString());
      // LoggingSystem.getLogger().log( Level.WARNING, "Could not open: " + f);
     }
    return null;
   }
  byte[] readByteArrayFile(URL lurl)
   {
    return readByteArrayFile(lurl,Integer.MAX_VALUE); 
   }
  byte[] readByteArrayFile(URL lurl,long maxlength)
   {
    byte[] ba=null;
    tta("readByteArrayFile lurl:"+lurl);
    try
     {
      InputStream is = lurl.openStream();
      DataInputStream dis = new DataInputStream(is);
      long fs=dis.available();
      tta("File size:"+fs);
      if(fs>Integer.MAX_VALUE)
       {
        // File is too large
       }
      else if(fs > maxlength)
       {
        //Also too large
       }
      ba=new byte[(int)fs];
      dis.readFully(ba);
      dis.close();
     }
    catch (IOException e)
     {
      tta("readByteArrayFile for URL and long -- Error with lurl:"+lurl+" reason is:"+ e.toString());
      //        throw new JmeException("Could not read: " + f);
     }
    return ba;
   }
  byte[] readbytefile(String fn)
   {
    byte[] bytes=null;
    try 
     {
      File file=new File(fn);
      tta("readbytefile:"+file);
      InputStream is = new FileInputStream(file);
      long length = file.length();
      if (length > Integer.MAX_VALUE)
       {
        // File is too large
       }
      bytes = new byte[(int)length];
      int offset = 0;
      int bufflength=1024*1024;
      while(bufflength>0)
       {
        offset+=is.read(bytes,offset,bufflength);
        if(offset+bufflength>length)bufflength=(int)(length-offset);
       }
      if(offset<bytes.length)
       {
        throw new IOException("Could not completely read file "+file.getName());
       }
      is.close();
     }
    catch( IOException e) { tta("error with readbytefile"); }
    return bytes;
   }
  byte[] orgreadbytefile(String fn)
   {
    byte[] bytes=null;
    try
     {
      File file=new File(fn);
      tta("readbytefile:"+file);
      InputStream is = new FileInputStream(file);
      long length = file.length();
      if (length > Integer.MAX_VALUE)
       {
        // File is too large
       }
      bytes = new byte[(int)length];
      int offset = 0;
      int bufflength=1024*1024;
      while(bufflength>0)
       {
        offset+=is.read(bytes,offset,bufflength);
        if(offset+bufflength>length)bufflength=(int)(length-offset);
       }
      if(offset<bytes.length)
       {
        throw new IOException("Could not completely read file "+file.getName());
       }
      is.close();
     }
    catch( IOException e) { tta("error with readbytefile"); }
    return bytes;
   }
  byte[] readbytefile(String fn,long l)
   {
    long length=l;
    byte[] bytes=null;
    try
     {
      File file=new File(fn);
      long fl=file.length();
      tta("readbytefile file:"+file+"  file.length:"+fl);
      if(length > fl) length=fl;
      else
       {
        tta("file will be trunkated to:"+length);
       }
      if (length > Integer.MAX_VALUE)
       {
        // File is too large
       }
      InputStream is = new FileInputStream(file);
      bytes = new byte[(int)length];
      int offset = 0;
      int bufflength=1024*1024;  // mach d
      //int bufflength=1*1024;  AJLogo1040
      if(offset+bufflength> length) bufflength=(int)(length-offset); // machd
      while(bufflength>0)
       {
        offset+=is.read(bytes, offset,bufflength);
        if(offset+bufflength> length) bufflength=(int)(length-offset);
       }
      if (offset < bytes.length)
       {
        throw new IOException("Could not completely read file "+file.getName());
       }
      is.close();
     }
    catch( IOException e) { tta("error with readbytefile"); }
    return bytes;
   }
  int readByte(String fh)
   {
    int i=0;
    DataInput dia=(DataInput)diah.get(fh);
    if(dia == null) tta("error dia is null");
    try { i=dia.readUnsignedByte(); }
    catch( IOException e)
     {
      //tta("error with readUnsignedByte()");
      i=-1;
     }
    return i;
   }
  String readLine(String fh)
   {
    String sa="";
    DataInput  dia=(DataInput)diah.get(fh);
    if(dia == null) return "error with readLine DataInput fh:"+fh;
    try { sa=dia.readLine(); }
    catch( IOException e) { return "error with readLine()"; }
    return sa;
   }
  void rclose(String fh)
   {
    try { ((FileInputStream)fish.get(fh)).close(); }
    catch(IOException e) { tta("rclose error"); }
   }
  void close(String fh)
   {
    try { ((FileOutputStream)fosh.get(fh)).close(); }
    catch(IOException e) { tta("error close"); }
   }
  public void wopen(String fh,String fn)
   {
    FileOutputStream fos=null;
    try { fosh.put(fh,fos=new FileOutputStream(fn)); }
    catch( IOException e) { tta("wopen error\n"); }
    doah.put(fh,new DataOutputStream(fos));
   }
  public DataInput openURL(URL lurl)
   {
    deb("Fio openURL lurl:"+lurl);
    URLConnection connection=null;
    DataInputStream dia;
    try { connection = lurl.openConnection(); }
    catch(IOException e) { return null; }
    try { dia = new DataInputStream(connection.getInputStream()); }
    catch(IOException e) { return null; }
    return dia;
   }
  void loadFt(String fn)
   {
    URL lurl;
    try
     {
      lurl = new URL("fonts/Arial.ttf");
      InputStream is;
      try
       {
        is = lurl.openStream();
        Font zont;
        try
         {
          try
           {
            zont = Font.createFont(Font.TRUETYPE_FONT, is);
           }
          catch(FontFormatException e) { }
         }
        catch(IOException e) {}
       }
      catch(MalformedURLException e) { }
     }
    catch(IOException e) {}
   }
  String preploadImg(String fn)
   {
    //tta("Fio.preploadImg fn:"+fn);
    if(fn.indexOf("/")== -1) fn="images/"+fn;  // try this
    //tta("Fio.preploadImg fn:"+fn);
    return fn;
   }
  Img loadImg(String fn)
   {
    //tta("Fio.loadImg(fn)   fn:"+fn+" filescodebase:"+filescodebase+"  going to Fio.loadImg (url,fn)");
    return loadImg(filescodebase,fn);
   }
  Img loadImg(URL codebase,String f)
   {
    //  filescodebase=new URL("file:///webroot/ajlogo/html/ajlogo/version3beta/"); 
    String forurl="";
    String fn=preploadImg(f);
    //tta("Fio.loadImg(codebase,fn) codebase:"+codebase+ " f:"+f+" fn:"+fn);
    //codebase=parent.codebase;
    if(fn.indexOf("http")> 0)
     {
      forurl=fn;
      tta("Fio.loadImg   fn.index of http>0  forurl:"+forurl);
     }
    if(parent.isApplet && forurl.equals(""))
     {
      tta("Fio.loadImg what is this");
     }
    if(forurl.equals("")) 
     {
      //tta("Fio.loadImg  forurl.equals \"\"  forurl:"+forurl);
      if(fn.indexOf("/webroot") ==0 )
       {
        //tta("FioloadImg(U,S) fn has /webroot set forurl to fn:"+fn);
        forurl=fn;
       }
      else
       {
        forurl=codebase+fn;
        //tta("Fio.loadImg  if \"\" else forurl:"+forurl);
       }
      //  tta("Fio.loadImg(U,S)  bottom of forurl.equals \"\" forurl:"+forurl);
     }
    Image image;
    Img img=null;
    if(! forurl.equals(""))
     {
      try { url = new URL(forurl); }
      catch(MalformedURLException e) { tta("Fio.loadImg forurl was malformed:"+forurl); }
      //tta("Fio.loadImg(U,S) forurl:"+forurl+"  fn:"+fn+" url:"+url);
      //tta("Fio.loadImg(U,S) calling getImage(url) url:"+url);
      image =Toolkit.getDefaultToolkit().getImage(url);
     }
    else
     { 
      //tta("Fio.loadImg(U,S) 2nd forurl is empty  using getImage(fn)  fn:"+fn);
      image =Toolkit.getDefaultToolkit().getImage(fn); 
     }
    //MediaTracker tracker = new MediaTracker(this);
    tracker.addImage(image,0);
    try { tracker.waitForID(0); }
    catch(InterruptedException e) { e.printStackTrace(); }
    //tta("Fio.loadImg(U,s)   fn:"+fn);
    if(image==null) tta("Fio.loadImg(U,S) Img is null");
    else img=Img.mkImg(image);
    image.flush();
    return img;
   }
  void plotS(String s)
   {
    try
     {
      FileOutputStream fos = new FileOutputStream("/dev/lp0");
      for(int i=0;i<s.length();i++) fos.write((byte)s.charAt(i));
      fos.write((byte)0xC);
      fos.close();
     }
    catch (Throwable e)
     {
      System.err.println("*** exception ***"+e.toString());
     }
   }
  int ppr() { return 0xaa55; }
  void ppw(int a) {  }
  //int ppr() { return lpt1.read(); }
  //void ppw(int a) { lpt1.write(a); }
  void tta(String s) { parent.tta(s); }
  void deb(String s) { if(deb) tta(s); }
  void ttace(String s) { parent.ttace(s); }
  void ttancr(String s) { parent.ttancr(s); }
 }
