Back to index

wims  3.65+svn20090927
Construction.java
Go to the documentation of this file.
00001 package rene.zirkel.construction;
00002 
00003 // file: ZirkelCanvas.java
00004 
00005 import java.util.*;
00006 import rene.util.*;
00007 import rene.util.sort.Sorter;
00008 import rene.util.xml.*;
00009 import rene.zirkel.Zirkel;
00010 import rene.zirkel.ZirkelCanvas;
00011 import rene.zirkel.ZirkelFrame;
00012 import rene.zirkel.constructors.*;
00013 import rene.zirkel.listener.*;
00014 import rene.zirkel.objects.*;
00015 import rene.zirkel.tools.*;
00016 import rene.zirkel.expression.*;
00017 import rene.gui.Global;
00018 
00027 public class Construction
00028 {      static final long serialVersionUID=Zirkel.Version;
00029        public Vector V; // The vector of objects (ConstructionObject's)
00030        public Vector Parameters; // The vector of parameter object names (String's)
00031        public Vector Targets; // The vector of target object names (String's)
00032        public String Comment="",JobComment="";
00033        public Vector PromptFor=new Vector();
00034        public Vector Prompts;
00035        private double X=0,Y=0,W=8,H=8; // H is set by ZirkelCanvas
00036        public boolean 
00037               Partial=Global.getParameter("options.partial",false),
00038               Restricted=Global.getParameter("options.restricted",true),
00039               PartialLines=Global.getParameter("options.plines",false),
00040               Vectors=Global.getParameter("options.arrow",false),
00041               ShowNames=Global.getParameter("options.shownames",false),
00042               ShowValues=Global.getParameter("options.showvalues",false),
00043               LongNames=Global.getParameter("options.longnames",false),
00044               LargeFont=Global.getParameter("options.largefont",false),
00045               BoldFont=Global.getParameter("options.boldfont",false),
00046               Hidden=false,
00047               Obtuse=Global.getParameter("options.obtuse",false),
00048               Solid=Global.getParameter("options.solid",false);
00049        public boolean Animate=false,Paint=false; // for loading tracks
00050        public boolean ShowAll=false; // for macros
00051        public boolean SuperHide=false; // for macros
00052        public int
00053               DefaultColor=Global.getParameter("options.color",0),
00054               DefaultType=Global.getParameter("options.type",0),
00055               DefaultColorType=Global.getParameter("options.colortype",0);
00056        public boolean Changed=false;
00057        int Count=0; // Unique number for each object
00058        public Construction TranslateInto;
00059        public boolean BlockSimulation=false; // To block two simulations at once! 
00060        public boolean DontAlternateIntersections=false; // To block alternating invalid intersections
00061        
00062        ObjectConstructor ObjectConstructors[]=
00063        // Constructors for reading a construction from file    
00064               {      new PointConstructor(),
00065                      new LineConstructor(),
00066                      new SegmentConstructor(),
00067                      new RayConstructor(),
00068                      new CircleConstructor(),
00069                      new IntersectionConstructor(),
00070                      new ParallelConstructor(),
00071                      new PlumbConstructor(),
00072                      new Circle3Constructor(),
00073                      new MidpointConstructor(),
00074                      new AngleConstructor(),
00075                      new BoundedPointConstructor(),
00076                      new ExpressionConstructor(),
00077                      new AreaConstructor(),
00078                      new TextConstructor(),
00079                      new QuadricConstructor(),
00080                      new ImageConstructor(),
00081                      new ObjectTracker(),
00082                      new FunctionConstructor()
00083               };
00084        
00085        public Construction ()
00086        {      clear(); Changed=false;
00087        }
00088        
00089        private AddEventListener AEL=null;
00090 
00091        public void addAddEventListener (AddEventListener ael)
00092        {      AEL=ael;
00093        }
00094 
00095        public void removeAddEventListener (AddEventListener ael)
00096        {      AEL=null;
00097        }
00098        
00103        public void add (ConstructionObject o)
00104        {      if (!o.isGotNCount()) o.setNCount(Count++); // give count
00105               else o.setGotNCount(false); 
00106               V.addElement(o);
00107               if (!Undo.isEmpty()) Undo.removeAllElements(); // clear undo
00108               o.setConstruction(this);
00109               if (AEL!=null) AEL.added(this,o); // note add listener
00110               haveChanged(); // set changed flag
00111               // System.out.println(o.getName()+" "+o.getNCount());
00112        }
00113 
00119        public void addNoCheck (ConstructionObject o)
00120        // add a new object
00121        {      if (!o.isGotNCount()) o.setNCount(Count++); // give count
00122               else o.setGotNCount(false); 
00123               V.addElement(o);
00124               if (!Undo.isEmpty()) Undo.removeAllElements();
00125               o.setConstruction(this);
00126               haveChanged();
00127        }
00128 
00129        public void added (ConstructionObject o)
00130        {      if (AEL!=null) AEL.added(this,o);
00131        }
00132 
00136        public synchronized void clear ()
00137        {      V=new Vector();
00138               if (!Undo.isEmpty()) Undo.removeAllElements();
00139               Comment="";
00140               JobComment="";
00141               clearParameters(); clearTargets();
00142               Prompts=new Vector();
00143               X=0; Y=0; W=8;
00144               Changed=false;
00145               Count=0;
00146        }
00147        
00148        Vector Undo=new Vector();
00149        
00153        public void back ()
00154        {      ConstructionObject o=last();
00155               if (o==null) return;
00156               o.setInConstruction(false);
00157               Undo.addElement(o);
00158               if (V.size()>0) V.removeElementAt(V.size()-1);
00159               updateCircleDep();
00160               clearParameters(); clearTargets();
00161               haveChanged();
00162        }
00163        
00168        public void delete (boolean clearUndo)
00169        {      if (clearUndo && !Undo.isEmpty()) Undo.removeAllElements();
00170               for (int i=V.size()-1; i>=0; i--)
00171               {      ConstructionObject o=(ConstructionObject)V.elementAt(i);
00172                      if (o.isFlag() && !o.isJobTarget())
00173                      {      o.setInConstruction(false);
00174                             Undo.addElement(o);
00175                             V.removeElementAt(i);
00176                      }
00177               }
00178               updateCircleDep();
00179               clearParameters(); 
00180               clearTargets();
00181               haveChanged();
00182        }
00183        public void delete ()
00184        {      delete(true);
00185        }
00186        
00190        public void undo ()
00191        {      if (Undo.isEmpty()) return;
00192               ConstructionObject o[]=new ConstructionObject[Undo.size()];
00193               Undo.copyInto(o);
00194               for (int i=o.length-1; i>=0; i--)
00195               {      V.addElement(o[i]);
00196                      o[i].setConstruction(this);
00197               }
00198               Undo.removeAllElements();
00199               haveChanged();
00200        }
00201        
00202        public Enumeration elements ()
00203        // enumerate all objects
00204        {      return V.elements();
00205        }
00206        
00207        public Enumeration getSortedElements ()
00208        {      ConstructionObject o[]=new ConstructionObject[V.size()];
00209               V.copyInto(o);
00210               for (int i=0; i<o.length; i++) o[i].Value=(o[i].getNCount());
00211               Sorter.sort(o);
00212               Vector v=new Vector();
00213               for (int i=0; i<o.length; i++) v.addElement(o[i]);
00214               return v.elements();
00215        }
00216 
00217        public ConstructionObject last ()
00218        {      if (V.size()>0) return (ConstructionObject)V.elementAt(V.size()-1);
00219               else return null;
00220        }
00221        
00222        public ConstructionObject lastByNumber ()
00223        {      ConstructionObject o=null;
00224               int maxCount=-1;
00225               Enumeration e=elements();
00226               while (e.hasMoreElements())
00227               {      ConstructionObject co=(ConstructionObject)e.nextElement();
00228                      if (co.getNCount()>maxCount)
00229                      {      maxCount=co.getNCount();
00230                             o=co;
00231                      }
00232               }
00233               return o;
00234        }
00235 
00236        public ConstructionObject lastButOne ()
00237        {      if (V.size()>1) return (ConstructionObject)V.elementAt(V.size()-2);
00238               else return null;
00239        }
00240        
00241        public void clearAfter (ConstructionObject after)
00242        {      while (true)
00243               {      ConstructionObject o=last();
00244                      if (o==null || o==after) break;
00245                      o.setInConstruction(false);
00246                      V.removeElementAt(V.size()-1);
00247                      haveChanged();
00248               }
00249               updateCircleDep();
00250               clearParameters(); clearTargets(); 
00251        }
00252 
00253        public String getComment ()
00254        {      return Comment;
00255        }
00256        
00257        public void setComment (String s)
00258        {      if (s.length()<=2) s="";
00259               Comment=s;
00260        }
00261        
00262        public double getX () { return X; }
00263        public double getY () { return Y; }
00264        public double getW () { return W; }
00265        public double getH () { return H; }
00266        public void setH (double h) { H=h; }
00267        public void setXYW (double x, double y, double w)
00268        {      X=x; Y=y; W=w;
00269        }
00270        
00271        public void save (XmlWriter xml)
00272        {      Enumeration e=elements();
00273               while (e.hasMoreElements())
00274               {      ((ConstructionObject)e.nextElement()).save(xml);
00275               }
00276               Changed=false;
00277        }
00278 
00279        public String TrackP=null,TrackPM=null,TrackO=null,AnimateP=null;
00280        public Vector TrackPO;
00281        public Vector AnimateV=null;
00282        public int Omit=0;
00283        public boolean AnimateNegative=false;
00284        public boolean AnimateOriginal=false;
00285        public String AnimateDelay=null;
00286        public String Icons="";
00287        public boolean AnimateBreakpoints=false;
00288        public long AnimateTime=1000;
00289        public boolean AnimateLoop=false;
00290        public boolean ResizeBackground=false;
00291        public String BackgroundFile=null;
00292        
00293        public synchronized void load (XmlTree tree, ZirkelCanvas zc)
00294               throws ConstructionException
00295        {      Enumeration root=tree.getContent();
00296               TrackP=null;
00297               TrackPO=new Vector();
00298               AnimateP=null;
00299               AnimateNegative=false;
00300               AnimateOriginal=false;
00301               AnimateBreakpoints=false;
00302               AnimateLoop=false;
00303               AnimateTime=1000;
00304               Icons="";
00305               BackgroundFile=null;
00306               ResizeBackground=false;
00307               zc.clearDrawings();
00308               while (root.hasMoreElements())
00309               {      tree=(XmlTree)root.nextElement();  
00310                      XmlTag tag=tree.getTag();
00311                      if (tag.name().equals("Comment"))
00312                      {      try
00313                             {      setComment(tree.parseComment());
00314                             }
00315                             catch (Exception e)
00316                             {      throw new ConstructionException("Illegal Comment");
00317                             }
00318                      }
00319                      else if (tag.name().equals("Assignment"))
00320                      {      try
00321                             {      setJobComment(tree.parseComment());
00322                             }
00323                             catch (Exception e)
00324                             {      throw new ConstructionException("Illegal Assignment");
00325                             }
00326                      }
00327                      else if (tag.name().equals("Track"))
00328                      {      if (!tag.hasParam("track"))
00329                                    throw new ConstructionException(
00330                                           Zirkel.name("exception.track"));
00331                             TrackP=tag.getValue("track");
00332                             TrackPO=new Vector();
00333                             int i=0;
00334                             while (tag.hasParam("track"+i))
00335                             {      TrackPO.addElement(tag.getValue("track"+i));
00336                                    i++;
00337                             }
00338                             if (tag.hasParam("move")) TrackPM=tag.getValue("move");
00339                             else TrackPM=null;
00340                             if (tag.hasParam("on")) TrackO=tag.getValue("on");
00341                             else TrackO=null;
00342                             Animate=false; Paint=true;
00343                             if (tag.hasParam("animate"))
00344                             {      if (tag.getValue("animate").equals("nopaint")) Paint=false;
00345                                    Animate=true;
00346                             }
00347                             Omit=0;
00348                             if (tag.hasParam("omit"))
00349                             {      try
00350                                    {      Omit=Integer.parseInt(tag.getValue("omit"));
00351                                    }
00352                                    catch (Exception e) {}
00353                             }
00354                      }
00355                      else if (tag.name().equals("Animate"))
00356                      {      if (!tag.hasParam("animate") || !tag.hasParam("via0"))
00357                                    throw new ConstructionException(
00358                                           Zirkel.name("exception.animate"));
00359                             AnimateP=tag.getValue("animate");
00360                             int k=0;
00361                             AnimateV=new Vector();
00362                             while (tag.hasParam("via"+k))
00363                             {      AnimateV.addElement(tag.getValue("via"+k));
00364                                    k++;
00365                             }
00366                             AnimateNegative=false;
00367                             if (tag.hasParam("negative") && 
00368                                           tag.getValue("negative").equals("true"))
00369                                    AnimateNegative=true;
00370                             if (tag.hasParam("original") && 
00371                                           tag.getValue("original").equals("true"))
00372                                    AnimateOriginal=true;
00373                             AnimateDelay=null;
00374                             if (tag.hasParam("delay"))
00375                             {      AnimateDelay=tag.getValue("delay");
00376                             }
00377                      }
00378                      else if (tag.name().equals("AnimateBreakpoints"))
00379                      {      AnimateBreakpoints=true;
00380                             try
00381                             {      if (tag.hasParam("time"))
00382                                    {      AnimateTime=new Long(tag.getValue("time")).longValue();
00383                                    }
00384                                    if (tag.hasParam("loop"))
00385                                    {      AnimateLoop=true;
00386                                    }
00387                             }
00388                             catch (Exception e)
00389                             {      throw new ConstructionException("exception.animate");
00390                             }
00391                      }
00392                      else if (tag.name().equals("Window"))
00393                      {      try
00394                             {      if (tag.hasParam("x"))
00395                                           X=new Double(tag.getValue("x")).doubleValue();
00396                                    if (tag.hasParam("y"))
00397                                           Y=new Double(tag.getValue("y")).doubleValue();
00398                                    if (tag.hasParam("w"))
00399                                           W=new Double(tag.getValue("w")).doubleValue();
00400                                    zc.ShowGrid=tag.hasTrueParam("showgrid");
00401                             }
00402                             catch (Exception e)
00403                             {      throw new ConstructionException("Illegal Window Parameters");
00404                             }                           
00405                      }
00406                      else if (tag.name().equals("Grid"))
00407                      {      try
00408                             {      if (tag.hasParam("color"))
00409                                    {      int n=new Integer(tag.getValue("color")).intValue();
00410                                           if (n>=0 && n<ZirkelFrame.Colors.length)
00411                                                  zc.GridColor=n;
00412                                    }
00413                                    if (tag.hasParam("thickness"))
00414                                    {      int n=new Integer(tag.getValue("thickness")).intValue();
00415                                           if (n>=0 && n<4)
00416                                                  zc.GridThickness=n;
00417                                    }
00418                                    zc.GridLabels=!(tag.hasTrueParam("nolables"));
00419                                    zc.GridLarge=tag.hasTrueParam("large");
00420                                    zc.GridBold=tag.hasTrueParam("bold");
00421                                    zc.AxesOnly=tag.hasTrueParam("axesonly");
00422                             }
00423                             catch (Exception e)
00424                             {      throw new ConstructionException("Illegal Grid Parameters");
00425                             }
00426                      }
00427                      else if (tag.name().equals("Background"))
00428                      {      try
00429                             {      if (tag.hasTrueParam("resize"))
00430                                           ResizeBackground=true;
00431                                    BackgroundFile=tag.getValue("file");
00432                                    if (BackgroundFile==null) 
00433                                           throw new ConstructionException("Illegal Background Parameters");
00434                             }
00435                             catch (Exception e)
00436                             {      throw new ConstructionException("Illegal Background Parameters");
00437                             }                           
00438                      }
00439                      else if (tag.name().equals("Draw"))
00440                      {      zc.loadDrawings(tree);
00441                      }
00442                      else if (tag.name().equals("Objects"))
00443                      {      // System.out.println("reading objects");
00444                             readConstruction(tree);
00445                             // System.out.println("finished reading objects");
00446                             updateCount();
00447                             computeNeedsOrdering();
00448                             //System.out.println("needs ordering: "+NeedsOrdering);
00449                             doOrder();
00450                             //System.out.println("finished reading objects");
00451                             break;
00452                      }
00453                      else if (tag.name().equals("Restrict"))
00454                      {      if (!tag.hasParam("icons"))
00455                                    throw new ConstructionException("Illegal Window Parameters");
00456                             Icons=tag.getValue("icons");
00457                      }
00458               }
00459        }
00460        
00461        public void translateOffsets (ZirkelCanvas zc)
00462        {      Enumeration e=V.elements();
00463               while (e.hasMoreElements())
00464               {      ((ConstructionObject)e.nextElement()).translateOffset(zc);
00465               }
00466        }
00467        
00468        public synchronized void readConstruction (XmlTree tree)
00469               throws ConstructionException
00470        {      Enumeration e=tree.getContent();
00471               //System.out.println("start reading tree");
00472               while (e.hasMoreElements())
00473               {      tree=(XmlTree)e.nextElement();
00474                      int i,n=ObjectConstructors.length;
00475                      for (i=0; i<n; i++)
00476                      {      try
00477                             {      if (ObjectConstructors[i].construct(tree,this)) break;
00478                             }
00479                             catch (ConstructionException ex)
00480                             {      if (tree.getTag().hasParam("name"))
00481                                    {      String name=tree.getTag().getValue("name");
00482                                           throw new ConstructionException(
00483                                                  ex.getDescription()+" (in "+name+")");
00484                                    }
00485                                    else throw ex;
00486                             }
00487                      }
00488                      if (i>=n) throw 
00489                             new ConstructionException(tree.getTag().name()+" unknown!");
00490               }
00491               //System.out.println("end reading tree");
00492               e=V.elements();
00493               while (e.hasMoreElements())
00494               {      ((ConstructionObject)e.nextElement()).laterBind(this);
00495               }
00496               //System.out.println("finished later bind");
00497               dovalidate();
00498               updateCircleDep();
00499               Changed=false;
00500               //System.out.println("finished circle dep");
00501        }
00502 
00508        public ConstructionObject find (String name)
00509        {      Enumeration e=V.elements();
00510               while (e.hasMoreElements())
00511               {      ConstructionObject c=(ConstructionObject)e.nextElement();
00512                      if (c.getName().equals(name)) return c;
00513               }
00514               return null;
00515        }
00516        
00523        public ConstructionObject find (String name, ConstructionObject until)
00524        {      Enumeration e=V.elements();
00525               while (e.hasMoreElements())
00526               {      ConstructionObject c=(ConstructionObject)e.nextElement();
00527                      if (c==until) break;
00528                      if (c.getName().equals(name)) return c;
00529               }
00530               return null;
00531        }
00532        
00539        public ConstructionObject findInclusive (String name, ConstructionObject until)
00540        {      Enumeration e=V.elements();
00541               while (e.hasMoreElements())
00542               {      ConstructionObject c=(ConstructionObject)e.nextElement();
00543                      if (c.getName().equals(name)) return c;
00544                      if (c==until) break;
00545               }
00546               return null;
00547        }
00548 
00552        public boolean before (ConstructionObject first,
00553               ConstructionObject second)
00554        {      Enumeration e=V.elements();
00555               while (e.hasMoreElements())
00556               {      ConstructionObject c=(ConstructionObject)e.nextElement();
00557                      if (c==first) return true;
00558                      if (c==second) break;
00559               }
00560               return false;
00561        }
00562        
00566        public boolean dependsDirectlyOn (ConstructionObject o, ConstructionObject on)
00567        {      Enumeration e=o.depending();
00568               while (e.hasMoreElements())
00569               {      if (on==e.nextElement()) return true;
00570               }
00571               return false;
00572        }
00573        
00577        public void clearRekFlags ()
00578        {      Enumeration e=elements();
00579               while (e.hasMoreElements())
00580               {      ConstructionObject o=(ConstructionObject)e.nextElement();
00581                      o.setRekFlag(false);
00582               }
00583        }      
00584        
00591        public boolean dependsOn (ConstructionObject o, ConstructionObject on)
00592        {      clearRekFlags(); // used as markers
00593               boolean res=dependsOnRek(o,on);
00594               return res;
00595        }
00596        
00604        public boolean dependsOnRek (ConstructionObject o, ConstructionObject on)
00605        {      //System.out.println(o.getName()+" depends on "+on.getName()+"?");
00606               o.setRekFlag(true);
00607               if (o==on) return true;
00608               ConstructionObject o1[]=o.getDepArray();
00609               for (int i=0; i<o1.length; i++)
00610               {      // System.out.println(o.getName()+" - check: "+o1[i].getName());
00611                      if (o1[i]==o || o1[i].isRekFlag()) continue;
00612                      // System.out.println("flag not set.");
00613                      if (dependsOnRek(o1[i],on)) return true;
00614               }
00615               return false;
00616        }
00617        
00624        public void reorderConstruction ()
00625        {      // Get the objects into a faster array
00626               ConstructionObject o[]=new ConstructionObject[V.size()];
00627               V.copyInto(o);
00628               int n=o.length;
00629               if (n==0) return;
00630               // Compute tail chain length for all objects recursively
00631               for (int i=0; i<n; i++) 
00632               {      o[i].Scratch=0; 
00633                      o[i].Flag=false; 
00634               }
00635               for (int i=0; i<n; i++)
00636               {      countTail(((ConstructionObject)o[i]));
00637                      /* 
00638                      // Test print:
00639                      System.out.println(((ConstructionObject)o[i]).getName()+" "+
00640                                    ((ConstructionObject)o[i]).Scratch);
00641                      Enumeration e=((ConstructionObject)o[i]).depending();
00642                      while (e.hasMoreElements())
00643                      {      System.out.println("- "+((ConstructionObject)e.nextElement()).getName());
00644                      }
00645                      */
00646               }
00647               // Sort the array using bubble sort (least distroying sort)
00648               if (n<500)
00649               {      for (int i=1; i<n; i++)
00650                      {      int k=o[i].Scratch;
00651                             int j=i;
00652                             while (j>0 && (o[j-1]).Scratch>k) j--;
00653                             if (j<i)
00654                             {      ConstructionObject oh=o[i];
00655                                    for (int h=i; h>j; h--) o[h]=o[h-1];
00656                                    o[j]=oh;
00657                             }
00658                      }
00659               }
00660               else // Use quick sort
00661               {      for (int i=0; i<o.length; i++) o[i].Value=o[i].Scratch;
00662                      Sorter.sort(o);
00663               }
00664               // Copy back all objects into the construction
00665               V=new Vector();
00666               for (int i=0; i<n; i++) V.addElement(o[i]);
00667        }
00668        
00677        public int countTail (ConstructionObject o)
00678        {      if (o.Flag) return o.Scratch;
00679               o.Flag=true;
00680               int max=0;
00681               ConstructionObject oc[]=o.getDepArray();
00682               if (oc.length==0)
00683               {      o.Scratch=0;
00684               }
00685               else
00686               {      for (int i=0; i<oc.length; i++)
00687                      {      if (oc[i]==o) continue;
00688                             int k=countTail(oc[i]);
00689                             if (k>max) max=k;
00690                      }
00691                      o.Scratch=max+1;
00692               }
00693               return o.Scratch;
00694        }
00695        
00696        boolean NeedsOrdering=false;
00697        
00701        public void needsOrdering ()
00702        {      NeedsOrdering=true;
00703        }
00704        
00708        public void doOrder ()
00709        {      if (!NeedsOrdering) return;
00710               reorderConstruction();
00711               NeedsOrdering=false;
00712        }
00713        
00718        public void computeNeedsOrdering ()
00719        {      // none checked so far
00720               Enumeration e=V.elements();
00721               while (e.hasMoreElements())
00722               {      ((ConstructionObject)e.nextElement()).Flag=false;
00723               }
00724               // check all
00725               e=V.elements();
00726               while (e.hasMoreElements())
00727               {      Enumeration ec=((ConstructionObject)e.nextElement()).depending();
00728                      while (ec.hasMoreElements())
00729                      {      if (!((ConstructionObject)ec.nextElement()).Flag)
00730                             {      NeedsOrdering=true;
00731                                    return;
00732                             }
00733                      }
00734               }      
00735               NeedsOrdering=false;
00736        }
00737        
00743        public int indexOf (ConstructionObject o)
00744        {      return V.indexOf(o);
00745        }
00746        
00752        public ConstructionObject lastDep (ConstructionObject o)
00753        {      int res=-1;
00754               ConstructionObject ores=null;
00755               Enumeration e=o.depending();
00756               while (e.hasMoreElements())
00757               {      ConstructionObject u=(ConstructionObject)e.nextElement();
00758                      int i=indexOf(u);
00759                      if (i>res)
00760                      {      res=i; ores=u; 
00761                      }
00762               }
00763               return ores;
00764        }
00765        
00770        public boolean reorder (ConstructionObject o1, ConstructionObject o2)
00771        {      /*// old routine changing internal order
00772               int k1=indexOf(o1),k2=-1;
00773               if (o2!=null) k2=indexOf(o2);
00774               if (k1<=k2+1) return false;
00775               ConstructionObject o=lastDep(o1);
00776               if (o!=null && indexOf(o)>k2) return false;
00777               V.removeElement(o1);
00778               V.insertElementAt(o1,k2+1);
00779               */
00780               // new routine changing generation numbers
00781               int n=-1;
00782               if (o2!=null) n=o2.getNCount();
00783               Enumeration e=V.elements();
00784               while (e.hasMoreElements())
00785               {      ConstructionObject o=(ConstructionObject)e.nextElement();
00786                      if (o.getNCount()>n)
00787                      o.setNCount(o.getNCount()+1);
00788               }
00789               o1.setNCount(n+1);
00790               haveChanged();
00791               return true;
00792        }
00793        
00800        public void updateTexts (ConstructionObject o, String oldname)
00801        {      Enumeration e=V.elements();
00802               while (e.hasMoreElements())
00803               {      ConstructionObject u=(ConstructionObject)e.nextElement();
00804                      if (dependsDirectlyOn(u,o)) u.updateText();
00805               }
00806        }
00807        
00808        public String getJobComment ()
00809        {      return JobComment;
00810        }
00811        public void setJobComment (String s)
00812        {      JobComment=s;
00813        }
00814 
00815        public void updateCircleDep ()
00816        {      Enumeration e=V.elements();
00817               while (e.hasMoreElements())
00818               {      ((ConstructionObject)e.nextElement()).clearCircleDep();
00819               }
00820               e=V.elements();
00821               while (e.hasMoreElements())
00822               {      ((ConstructionObject)e.nextElement()).updateCircleDep();
00823               }
00824        }
00825        
00826        public Vector getParameters () { return Parameters; }
00827        public int countParameters ()
00828        {      if (Parameters==null) return 0;
00829               return Parameters.size();
00830        }
00831        public Vector getTargets () { return Targets; }
00832        public int countTargets ()
00833        {      if (Targets==null) return 0;
00834               return Targets.size();
00835        }
00836        
00837        public void addParameter (ConstructionObject o) { Parameters.addElement(o); }
00838        public void addTarget (ConstructionObject o) { Targets.addElement(o); }
00839        
00840        public void clearParameters ()
00841        {      Enumeration e=elements();
00842               while (e.hasMoreElements())
00843               {      ConstructionObject o=(ConstructionObject)e.nextElement();
00844                      o.clearParameter();
00845                      o.setSpecialParameter(false);
00846               }
00847               Parameters=new Vector(); 
00848        }
00849        public void clearTargets ()
00850        {      Enumeration e=elements();
00851               while (e.hasMoreElements())
00852               {      ConstructionObject o=(ConstructionObject)e.nextElement();
00853                      o.setTarget(false);
00854               }
00855               Targets=new Vector();
00856        }
00857 
00858        public void testParameter (ConstructionObject o)
00859               throws ConstructionException
00860        {      throw new ConstructionException(Zirkel.name("exception.null"));
00861        }      
00862 
00863        Interpreter Int=new Interpreter(this);
00864        
00869        public void interpret (ZirkelCanvas zc, String s, String comment)
00870               throws ConstructionException
00871        {      Int.interpret(zc,s,comment);
00872        }
00873        
00874        public void interpret (ZirkelCanvas zc, String s)
00875        throws ConstructionException
00876        {      Int.interpret(zc,s,"");
00877        }
00878        
00879        boolean IntersectionBecameInvalid;
00880        
00881        public void dovalidate ()
00882        {      doOrder(); // will do something only if necessary
00883               while (true)
00884               {      Enumeration e=elements();
00885                      boolean stop=true;
00886                      IntersectionBecameInvalid=false;
00887                      while (e.hasMoreElements())
00888                      {      ConstructionObject o=(ConstructionObject)e.nextElement();
00889                             boolean valid=o.valid();
00890                             o.validate();
00891                             if (o instanceof IntersectionObject && valid && !o.valid())
00892                             {      IntersectionBecameInvalid=true;
00893                             }
00894                             if (o.changedBy()>1e-6) stop=false;
00895                      }
00896                      if (stop) break;
00897               }
00898        }
00899        
00903        public boolean intersectionBecameInvalid ()
00904        {      return IntersectionBecameInvalid;
00905        }
00906        
00907        public void dovalidateDebug ()
00908        {      doOrder(); // will do something only if necessary
00909               System.out.println("--- Time validate() ---");
00910               while (true)
00911               {      Enumeration e=elements();
00912                      boolean stop=true;
00913                      while (e.hasMoreElements())
00914                      {      ConstructionObject o=(ConstructionObject)e.nextElement();
00915                             long time=System.currentTimeMillis();
00916                             for (int i=0; i<100; i++) o.validate();
00917                             time=System.currentTimeMillis()-time;
00918                             if (time>0)
00919                                    System.out.println(o.getName()+" - "+(time/100.0)+" msec");
00920                             if (o.changedBy()>1e-6) stop=false;
00921                      }
00922                      if (stop) break;
00923               }
00924        }
00925 
00931        public void validate (ConstructionObject o, ConstructionObject avoid)
00932        {      if (o.RekValidating) return; // should not happen!
00933               o.RekValidating=true;
00934               if (o.VRek==null) o.VRek=new MyVector();
00935               else o.VRek.removeAllElements();
00936               Enumeration e=elements();
00937               while (e.hasMoreElements())
00938               {      ((ConstructionObject)e.nextElement()).setRekFlag(false);
00939               }
00940               recursiveValidate(o,avoid);
00941               e=elements();
00942               while (e.hasMoreElements())
00943               {      ConstructionObject oc=(ConstructionObject)e.nextElement();
00944                      if (oc.isRekFlag()) o.VRek.addElement(oc);
00945               }
00946               // System.out.println("---");
00947               e=o.VRek.elements();
00948               while (e.hasMoreElements())
00949               {      ConstructionObject oc=(ConstructionObject)e.nextElement();
00950                      oc.validate();
00951                      // System.out.println("Validating "+oc.getName());
00952               }             
00953               o.RekValidating=false;
00954        }
00955        
00956        public void recursiveValidate (ConstructionObject o, ConstructionObject avoid)
00957        {      if (o.isRekFlag() || o==avoid) return;
00958               o.setRekFlag(true);
00959               ConstructionObject d[]=o.getDepArray();
00960               for (int i=0; i<d.length; i++)
00961               {      recursiveValidate(d[i],avoid);
00962               }
00963        }
00964        
00965        public void computeTracks (ZirkelCanvas zc)
00966        {      Enumeration e=elements();
00967               while (e.hasMoreElements())
00968               {      ConstructionObject o=(ConstructionObject)e.nextElement();
00969                      if (o instanceof TrackObject) ((TrackObject)o).compute(zc);
00970               }
00971        }
00972        
00973        public void clearTranslations ()
00974        {      Enumeration e=elements();
00975               while (e.hasMoreElements())
00976               {      ConstructionObject o=(ConstructionObject)e.nextElement();
00977                      o.setTranslation(null);
00978               }
00979        }
00980 
00987        public void determineConstructables ()
00988        {      Enumeration e=elements();
00989               while (e.hasMoreElements())
00990               {      ConstructionObject o=(ConstructionObject)e.nextElement();
00991                      if (o.isParameter()) o.setFlag(true);
00992                      else
00993                      {      Enumeration ee=o.depending();
00994                             boolean constructable=
00995                                           (o instanceof ExpressionObject || o instanceof FunctionObject);
00996                             while (ee.hasMoreElements())
00997                             {      ConstructionObject oo=
00998                                           (ConstructionObject)ee.nextElement();
00999                                    if (o!=oo)
01000                                    {      if (oo.isFlag()) constructable=true;
01001                                           else
01002                                           {      constructable=false; break;
01003                                           }
01004                                    }
01005                             }
01006                             o.setFlag(constructable);
01007                             // if (constructable) System.out.println(o.getName());
01008                      }
01009               }
01010        }
01011 
01020        public boolean determineConstructables (ConstructionObject o)
01021        {      if (o.isFlag()) return true;
01022               ConstructionObject dep[]=o.getDepArray();
01023               boolean constructable=
01024                      (o instanceof ExpressionObject || o instanceof FunctionObject);
01025               for (int i=0; i<dep.length; i++)
01026               {      if (dep[i]==null) return false;
01027                      if (dep[i]==o) continue;
01028                      if (!determineConstructables(dep[i])) return false;
01029                      else constructable=true;
01030               }
01031               o.setFlag(constructable);
01032               return true;
01033        }
01034        
01039        public void clearConstructables ()
01040        {      Enumeration e=elements();
01041               while (e.hasMoreElements())
01042               {      ConstructionObject o=(ConstructionObject)e.nextElement();
01043                      o.setFlag(false);
01044               }
01045        }
01046        
01052        public void determineChildren ()
01053        {      Enumeration e=elements();
01054               while (e.hasMoreElements())
01055               {      ConstructionObject o=(ConstructionObject)e.nextElement();
01056                      if (!o.isFlag())
01057                      {      Enumeration ee=o.depending();
01058                             while (ee.hasMoreElements())
01059                             {      ConstructionObject oo=
01060                                           (ConstructionObject)ee.nextElement();
01061                                    if (oo.isFlag())
01062                                    {      o.setFlag(true); break;
01063                                    }
01064                             }
01065                      }
01066               }
01067 
01068        }
01069 
01074        public void setParameterAsConstructables ()
01075        {      Enumeration e=elements();
01076               while (e.hasMoreElements())
01077               {      ConstructionObject o=(ConstructionObject)e.nextElement();
01078                      if (o.isParameter() || o.isMainParameter())
01079                             o.setFlag(true);
01080               }
01081        }
01082 
01083        public String[] getPromptFor ()
01084        {      String s[]=new String[PromptFor.size()];
01085               PromptFor.copyInto(s);
01086               return s;
01087        }
01088        
01089        boolean ShouldSwitch=false,NoteSwitch=false;
01090        
01091        public boolean shouldSwitch ()
01092        {      return ShouldSwitch;
01093        }
01094        
01095        public boolean noteSwitch ()
01096        {      return NoteSwitch;
01097        }
01098        
01099        public void shouldSwitch (boolean flag, boolean note)
01100        {      ShouldSwitch=flag; NoteSwitch=note;
01101        }
01102        
01103        public void shouldSwitch (boolean flag)
01104        {      ShouldSwitch=flag; NoteSwitch=true;
01105        }
01106        
01107        public void switchBack ()
01108        {      Enumeration e=elements();
01109               while (e.hasMoreElements())
01110               {      ConstructionObject o=(ConstructionObject)e.nextElement();
01111                      if (o instanceof IntersectionObject)
01112                             ((IntersectionObject)o).switchBack();
01113               }
01114        }
01115 
01116        public void clearSwitches ()
01117        {      Enumeration e=elements();
01118               while (e.hasMoreElements())
01119               {      ConstructionObject o=(ConstructionObject)e.nextElement();
01120                      if (o instanceof IntersectionObject)
01121                             ((IntersectionObject)o).switchBack();
01122               }
01123        }
01124 
01125        public boolean haveSwitched ()
01126        {      Enumeration e=elements();
01127               while (e.hasMoreElements())
01128               {      ConstructionObject o=(ConstructionObject)e.nextElement();
01129                      if (o instanceof IntersectionObject)
01130                             if (((IntersectionObject)o).isSwitched()) return true;
01131               }
01132               return false;
01133        }
01134 
01135        public boolean changed ()
01136        {      return Changed;
01137        }
01138        
01139        public ChangedListener CL=null;
01140        
01141        public void haveChanged ()
01142        {      changed(true);
01143               if (CL!=null) CL.notifyChanged();
01144        }
01145        
01146        public void changed (boolean flag)
01147        {      Changed=flag;
01148        }
01149        
01150        public MyVector TranslatorList=new MyVector();
01151 
01152        public void addTranslator (Translator t)
01153        {      TranslatorList.addElement(t);
01154        }
01155        
01156        public void runTranslators (Construction from)
01157        {      Enumeration e=TranslatorList.elements();
01158               while (e.hasMoreElements())
01159               {      Translator t=(Translator)e.nextElement();
01160                      t.laterTranslate(from);
01161               }
01162        }
01163        
01164        public void clearTranslators ()
01165        {      TranslatorList.removeAllElements();
01166        }
01167        
01172        public void updateCount ()
01173        {      int max=0;
01174               Enumeration e=V.elements();
01175               while (e.hasMoreElements())
01176               {      int n=((ConstructionObject)e.nextElement()).getNCount();
01177                      if (n>max) max=n;
01178               }
01179               Count=max+1;
01180        }
01181 
01182        Vector VOld=null;
01183        
01189        public void setOriginalOrder (boolean flag)
01190        {      if (V==null) return;
01191               if (flag)
01192               {      ConstructionObject o[]=new ConstructionObject[V.size()];
01193                      V.copyInto(o);
01194                      for (int i=0; i<o.length; i++) o[i].Value=(o[i].getNCount());
01195                      Sorter.sort(o);
01196                      Vector W=new Vector();
01197                      for (int i=0; i<o.length; i++) W.addElement(o[i]);
01198                      VOld=V;
01199                      V=W;
01200               }
01201               else if (VOld!=null)
01202               {      V=VOld;
01203                      VOld=null;
01204               }
01205        }
01206 
01207        public Construction getTranslation ()
01208        {      return TranslateInto;
01209        }
01210        
01211        public void setTranslation (Construction C)
01212        {      TranslateInto=C;
01213        }
01214 
01215        public boolean Loading=false;      
01216        
01217        public boolean loading () { return Loading; }
01218 
01219        Vector Errors=new Vector();
01220        
01221        public void addError (String s)
01222        {      Errors.addElement(s);
01223        }
01224        
01225        public Enumeration getErrors ()
01226        {      return Errors.elements();
01227        }
01228        
01229        public void clearErrors ()
01230        {      Errors.removeAllElements();
01231        }
01232 
01233        public void dontAlternate (boolean flag)
01234        {      DontAlternateIntersections=flag;
01235        }
01236        
01237        public boolean canAlternate ()
01238        {      return !DontAlternateIntersections;
01239        }
01240 
01241        double Pixel=100; // Pixel per unit
01242        
01248        public void setPixel (double pixel)
01249        {      Pixel=pixel;
01250        }
01251        
01252        public double getPixel ()
01253        {      return Pixel;
01254        }
01255 }
01256