import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.EventListener;
import java.util.*;
import java.awt.image.BufferedImage;
class LP extends JPanel  implements MouseListener, MouseMotionListener
 {
  static final double PI=Math.PI;
  static final double PIPI=2*Math.PI;
  static final double DR=PI/180;
  static final double RD=180/PI;
  static int ten=9;
  static int twenty=(int)(ten*2);
  static int thirty=ten*3;
  static int fourty=(int)(ten*4);
  static int fifty=(int)(ten*5);
  static int sixty=(int)(ten*6);
  static int seventy=(int)(ten*7);
  static int eighty=(int)(ten*8);
  static int ninety=(int)(ten*9);
  static int hundred=(int)(ten*10);
  static int oneten=(int)(ten*11);
  static int onetwenty=(int)(ten*12);
  static int oneeighty=(int)(ten*18);
  static boolean edlppos=false;
  static boolean edpos=false;
  Rec rec,body;
  K pk=new K(Color.black);
  K bk=new K(Color.white);
  static M parent;
  String name;
  String host,hosttype;
  double pw;
  dP tl,tldrgoff;
  dP mp,md,mr;
  Graphics2D onsg,offsg;
  BufferedImage offsimg;
  int nextx=0,nexty=0;
  Te te;
  Hashtable kidsh=new Hashtable();
  String[] kidsa=new String[1024];
  int nflayer=0;
  String pos;
  LP hostlp;
  LC hostlc;
  LScP hostlscp;
  LSpP hostlspp;
  LP() { te=parent.te; }
  LP(String name,LSpP lspp,String pos,Rec rec)
   {
    super();
    this.name=name;
    host=lspp.name;
    hostlspp=lspp;
    hosttype="LSpP";
    this.pos=pos;
    this.rec=rec;
    comm();
   }
  LP(String name,LScP lscp,Rec rec,K bk)
   {
    super();
    this.name=name;
    hostlscp=lscp;
    host=lscp.name;
    hosttype="LScP";
    this.rec=rec;
    this.bk=bk;
    comm();
   }
  LP(String name,LP lp,Rec rec,K bk)
   {
    super();
    this.name=name;
    hostlp=lp;
    host=hostlp.name;
    hosttype="LP";
    this.rec=rec;
    this.bk=bk;
    comm();
   }
  LP(String name,LC lc,Rec rec,K bk)
   {
    super();
    this.name=name;
    hostlc=lc;
    host=lc.name;
    hosttype="LC";
    this.rec=rec;
    this.bk=bk;
    comm();
   }
  void comm()
   {
    Te.LPh.put(name,this);
    setPreferredSize(new Dimension(rec.wi,rec.hi));
    tl=new dP(rec.xi,rec.yi);
    body=new Rec(rec);
    attach();
    setBounds(rec.xi,rec.yi,rec.wi,rec.hi);
    te=parent.te;
    if(te==null) tta("te is null");
    setLayout(null);
    setBackground(bk.c);
    addMouseListener(this);
    addMouseMotionListener(this);
    Te.LPh.put(name,this);
   }
  void clearmost()
   {
    nextx=0;
    nexty=0;
    kidsh=new Hashtable();
    kidsa=new String[1024];
    nflayer=0;
   }
  void attach(int l)
   {
    if(hosttype.equals("LSpP")) hostlspp.setlayer(this,pos,l);
    else if(hosttype.equals("LScP")) hostlscp.setlayer(this,l);
    else if(hosttype.equals("LP")) hostlp.setkidlayer(name,l);
    else if(hosttype.equals("LC")) hostlc.setlayer(this,l);
   }
  void attach() 
   {
    if(hosttype.equals("LSpP")) hostlspp.setlayer(this,pos);
    else if(hosttype.equals("LScP")) hostlscp.setlayer(this);
    else if(hosttype.equals("LP")) hostlp.setkidlayer(name);
    else if(hosttype.equals("LC")) hostlc.setlayer(this);
   }
  int getlayer()
   {
    if(hosttype.equals("LSpP")) return hostlspp.getlayer(this);
    else if(hosttype.equals("LScP")) return hostlscp.getlayer(this);
    else if(hosttype.equals("LP")) return hostlp.getkidlayer(name);
    else if(hosttype.equals("LC")) return hostlc.getlayer(this);
    return 0;
   }
  void packallkids()
   {
    tta("LP.packallkids()");
    nexty=0;
    int i=0;
    while(kidsa[i] != null && ! kidsa[i].equals(""))
     {
      if(Te.LPh.containsKey(kidsa[i]))
       {
        LP a=(LP)Te.LPh.get(kidsa[i]);
        a.settl(new dP(0,nexty));
        nexty+=a.rec.hi;
       }
      else if(Te.Buh.containsKey(kidsa[i]))
       {
        Bu a=(Bu)Te.Buh.get(kidsa[i]);
        a.settl(new dP(0,nexty));
        nexty+=a.rec.hi;
       }
      else if(Te.Menuh.containsKey(kidsa[i]))
       {
        Menu a=(Menu)Te.Menuh.get(kidsa[i]);
        a.settl(new dP(0,nexty));
        nexty+=a.rec.hi;
       }
      else if(Te.Slh.containsKey(kidsa[i]))
       {
        Sl a=(Sl)Te.Slh.get(kidsa[i]);
        a.settl(new dP(0,nexty));
        nexty+=a.rec.hi;
       }
      i++;
     }
   }
  void placeallkids()
   {
    removeAll();
    int i=0;
    while(kidsa[i] != null && ! kidsa[i].equals(""))
     {
      if(Te.LPh.containsKey(kidsa[i])) add((LP)Te.LPh.get(kidsa[i]));
      else if(Te.Buh.containsKey(kidsa[i])) add((Bu)Te.Buh.get(kidsa[i]));
      else if(Te.Menuh.containsKey(kidsa[i])) add((Menu)Te.Menuh.get(kidsa[i]));
      else if(Te.Slh.containsKey(kidsa[i])) add((Sl)Te.Slh.get(kidsa[i]));
      i++;
     }
   }
  int getkidlayer() { return getkidlayer(name); }
  int getkidlayer(String kid)
   {
    for(int i=0;i<nflayer;i++)
     {
      if(kidsa[i].equals(kid)) return i;
     }
    return -1;
   }
  void setkidlayer(String kid) { setkidlayer(kid,nflayer); }
  void setkidlayer() { setkidlayer(name,nflayer); }
  void setkidlayer(int l) { setkidlayer(name,l); }
  void setkidlayer(String kid,int l)
   {
    int j=getkidlayer(kid);
    if(l>nflayer) l=nflayer;
    if(j==l) return;
    if(l==nflayer)
     {
      if(j!= -1) return;
      kidsa[l]=kid;
      nflayer++;
     }
    else if(l==-1) //remove
     {
      for(int i=j;i<nflayer;i++)  kidsa[i]=kidsa[i+1];
      nflayer--;
     }
    else
     {
      if(j==-1)  //add new
       {
        for(int i=l;i<nflayer;i++)  kidsa[i+1]=kidsa[i];
        kidsa[l]=kid;
        nflayer++;
       }
      else //move
       {
        if(j<l)
         {
          for(int i=j;i<l;i++) kidsa[i]=kidsa[i+1];
          kidsa[l]=kid;
         }
        else
         {
          for(int i=j;i>l;i--) kidsa[i]=kidsa[i-1];
          kidsa[l]=kid;
         }
       }
     }
    placeallkids();
   }
  void setkids(String[] a) { kidsa=a; }
  void init()
   {
    onsg=(Graphics2D)getGraphics();
    if(offsimg != null) offsimg.flush();
    offsimg=new BufferedImage(rec.wi,rec.hi,BufferedImage.TYPE_INT_RGB);
    if(offsimg==null) tta("offsimg is null");
    offsg=offsimg.createGraphics();
    tl=new dP(rec.xi,rec.yi);
    clearscreen();
    spk(pk);
    spw(pw);
   }
  static void setedpos(boolean b) { edpos=b; }
  public void clearscreen() { fillRecbk(new Rec(0,0,rec.wi,rec.hi,rec.pk,rec.fk)); }
  synchronized void rRec(Rec r,Graphics2D g,boolean f,boolean p)
   {
    if(g==null) return;
    if(p) rRec(r,g,f,r.pk);
    else rRec(r,g,f,r.fk);
   }
  synchronized void rRec(Rec r,Graphics2D g,boolean f,K k)
   {
    if(g==null) return;
    g.setColor(k.c);
    if(f) g.fill(new Rectangle2D.Double(r.x,r.y,r.w,r.h));
    else g.draw(new Rectangle2D.Double(r.x,r.y,r.w,r.h));
    g.setColor(pk.c);
   }
  synchronized void fRecbk(Rec r) { rRec(r,offsg,true,r.fk); }
  synchronized void fRecpk(Rec r) { rRec(r,offsg,true,r.pk); }
  synchronized void fRec(Rec r,K k) { rRec(r,offsg,true,k); }
  synchronized void dRecbk(Rec r) { rRec(r,offsg,false,r.fk); }
  synchronized void dRecpk(Rec r) { rRec(r,offsg,false,r.pk); }
  synchronized void dRec(Rec r,K k) { rRec(r,offsg,false,k); }
  public void paintComponent(Graphics g)
   {
    if(hosttype.equals("LC"))
     {
     }
    else if(hosttype.equals("LP"))
     {
      if(hostlp.getSize().width != body.wi)
       {
        body.setw(hostlp.getSize().width);
        rec.setw(hostlp.getSize().width);
        setSize(new Dimension(rec.wi,rec.hi));
        setBounds(rec.xi,rec.yi,rec.wi,rec.hi);
        init();
       }
     }
    else
     {
      Rec newrec=new Rec(rec.x,rec.y,getSize());
      if(! rec.equals(newrec))
       {
        rec=newrec;
        init();
       }
     }
    super.paintComponent(g);
   }
  synchronized void fillRecbk(Rec rec)
   {
    if (offsg == null) return;
    offsg.setColor(rec.fk.c);
    fillRec(rec);
    offsg.setColor(pk.c);
   }
  synchronized void drawRecpk(Rec r)
   {
    if (offsg == null) return;
    offsg.setColor(r.pk.c);
    drawRec(r);
    offsg.setColor(pk.c);
   }
  synchronized void drawRecbk(Rec r)
   {
    if (offsg == null) return;
    offsg.setColor(r.fk.c);
    drawRec(r);
    offsg.setColor(pk.c);
   }
  synchronized void fillRecpk(Rec r)
   {
    if (offsg == null) return;
    offsg.setColor(r.pk.c);
    fillRec(r);
    offsg.setColor(pk.c);
   }
  synchronized void fillRec(Rec r)
   {
    if (offsg == null) return;
    offsg.fill(new Rectangle2D.Double(r.x,r.y,r.w,r.h));
   }
  synchronized void drawRec(Rec r)
   {
    if (offsg == null) return;
    Rectangle2D s=new Rectangle2D.Double(r.x,r.y,r.w,r.h);
    offsg.draw(s);
   }
  public void mousePressed(MouseEvent e)
   {
    mp=MEtodP(e);
    tldrgoff=mp;
   }
  public void mouseDragged(MouseEvent e)
   {
    md=MEtodP(e);
    if(edpos)
     {
      int cx=0;
      int cy=0;
      if(md.x-tldrgoff.x>45)  cx=45;
      else if(tldrgoff.x - md.x>45) cx=-45;
      if(md.y-tldrgoff.y >= 36)  cy=36;
      else if(md.y-tldrgoff.y>=27)  cy=36;
      else if(md.y-tldrgoff.y>=18)  cy=27;
      else if(md.y-tldrgoff.y>=9)  cy=18;
      else if(md.y-tldrgoff.y>=0)  cy=9;
      else if(md.y-tldrgoff.y<= -9) cy=-9;
      else if(md.y-tldrgoff.y<= -18) cy=-18;
      else if(md.y-tldrgoff.y<= -27) cy=-27;
      if(cx !=0 || cy != 0)
       {
        tl.ae(cx,cy);
        settl(tl);
       }
     }
   }
  public void mouseReleased(MouseEvent e) 
   {
   }
  public void mouseClicked(MouseEvent e) {}
  public void mouseEntered(MouseEvent e) {}
  public void mouseExited(MouseEvent e) {}
  public void mouseMoved(MouseEvent e) 
   {
    dP mm=MEtodP(e);
   }
  public void tta(String s) { parent.tta(s); }
  static void tta1(String s) { parent.tta1(s); }
  public void dofin()
   {
    if(hosttype.equals("LP"))
     {
      hostlp.remove(this);
      hostlp.doLayout();
      hostlp.repaint();
     }
   }
  public dP MEtodP(MouseEvent e) { return new dP(e.getPoint().x,e.getPoint().y); }
  synchronized void spk(K k)
   {
    pk=k;
    if(offsg != null) offsg.setColor(pk.c);
   }
  synchronized void spw(double d)
   {
    pw=d;
    if(offsg != null) offsg.setStroke(new BasicStroke((float)pw));
   }
  public void settl(dP tl)
   {
    this.tl=tl;
    rec=new Rec(tl.x,tl.y,body.wi,body.hi);
    setBounds(rec.xi,rec.yi,rec.wi,rec.hi);
    onsg=(Graphics2D)getGraphics();
   }
  void ed()
   {
    tta1(name+".tl "+Te.Svo(tl));
    tta1(name+".host "+host);
    tta1(name+".edpos "+Te.Svo(edpos));
    tta1(name+".nexty "+Te.Svo(nexty));
   }
  public void drawImg(Img img,dP dp,double scale)
   {
    Img imga=null;
    if(scale==100) imga=img;
    else imga=Img.scalelib(img,scale,scale);
    if (offsimg != null)
     {
      offsg.drawImage(imga,dp.xi,-imga.rec.hi-dp.yi,this);
     }
    repaint();
    onsg=(Graphics2D)getGraphics();
    onsg.drawImage(imga,dp.xi,-imga.rec.hi-dp.yi,this);
   }
 }
