1 /* $RCSfile$
2  * $Author: hansonr $
3  * $Date: 2006-02-25 17:19:14 -0600 (Sat, 25 Feb 2006) $
4  * $Revision: 4529 $
5  *
6  * Copyright (C) 2002-2005  The Jmol Development Team
7  *
8  * Contact: jmol-developers@lists.sf.net
9  *
10  *  This library is free software; you can redistribute it and/or
11  *  modify it under the terms of the GNU Lesser General Public
12  *  License as published by the Free Software Foundation; either
13  *  version 2.1 of the License, or (at your option) any later version.
14  *
15  *  This library is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  *  Lesser General Public License for more details.
19  *
20  *  You should have received a copy of the GNU Lesser General Public
21  *  License along with this library; if not, write to the Free Software
22  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24 
25 package org.jmol.shapecgo;
26 
27 import java.util.Hashtable;
28 import java.util.Map;
29 
30 import javajs.util.AU;
31 import javajs.util.Lst;
32 import javajs.util.PT;
33 import javajs.util.SB;
34 
35 import javajs.util.BS;
36 import org.jmol.script.T;
37 import org.jmol.shape.Mesh;
38 import org.jmol.shape.MeshCollection;
39 
40 public class CGO extends MeshCollection {
41 
42   CGOMesh[] cmeshes = new CGOMesh[4];
43   private CGOMesh cgoMesh;
44   private boolean useColix; // not implemented?
45   private float newScale; // not implemented
46   private int indicatedModelIndex = Integer.MIN_VALUE;
47 
48 
CGO()49   public CGO() {
50     // for reflection
51     myType = "CGO";
52     htObjects = new Hashtable<String, Mesh>();
53   }
54 
initCGO()55   private void initCGO() {
56     indicatedModelIndex = Integer.MIN_VALUE;
57   }
58 
59   @Override
allocMesh(String thisID, Mesh m)60   public void allocMesh(String thisID, Mesh m) {
61     int index = meshCount++;
62     meshes = cmeshes = (CGOMesh[]) AU.ensureLength(cmeshes,
63         meshCount * 2);
64     currentMesh = cgoMesh = cmeshes[index] = (m == null ? new CGOMesh(vwr, thisID,
65         colix, index) : (CGOMesh) m);
66     currentMesh.color = color;
67     currentMesh.index = index;
68     currentMesh.useColix = useColix;
69     currentMesh.modelIndex = indicatedModelIndex;
70     if (thisID != null && thisID != MeshCollection.PREVIOUS_MESH_ID
71         && htObjects != null)
72       htObjects.put(thisID.toUpperCase(), currentMesh);
73   }
74 
75   @SuppressWarnings("unchecked")
76   @Override
setProperty(String propertyName, Object value, BS bs)77   public void setProperty(String propertyName, Object value, BS bs) {
78 
79     if ("init" == propertyName) {
80       initCGO();
81       setPropertySuper("init", value, bs);
82       return;
83     }
84 
85     if ("setCGO" == propertyName) {
86       Lst<Object> list = (Lst<Object>) value;
87       setProperty("init", null, null);
88       int n = list.size() - 1;
89       setProperty("thisID", list.get(n), null);
90       propertyName = "set";
91       setProperty("set", value, null);
92       return;
93     }
94 
95     if ("modelIndex" == propertyName) {
96       indicatedModelIndex = Math.max(((Integer) value).intValue(), -1);
97       return;
98     }
99 
100     if ("set" == propertyName) {
101       if (cgoMesh == null) {
102         allocMesh(null, null);
103         cgoMesh.colix = colix;
104         cgoMesh.color = color;
105         cgoMesh.useColix = useColix;
106       }
107       cgoMesh.modelIndex = (indicatedModelIndex == Integer.MIN_VALUE ? vwr.am.cmi : indicatedModelIndex);
108       cgoMesh.isValid = setCGO((Lst<Object>) value);
109       if (cgoMesh.isValid) {
110         scale(cgoMesh, newScale );
111         cgoMesh.initialize(T.fullylit, null, null);
112         cgoMesh.title = title;
113         cgoMesh.visible = true;
114       }
115       clean();
116       return;
117     }
118 
119     if (propertyName == "deleteModelAtoms") {
120       deleteModels(((int[]) ((Object[]) value)[2])[0]);
121       return;
122     }
123 
124     setPropertySuper(propertyName, value, bs);
125   }
126 
deleteModels(int modelIndex)127   protected void deleteModels(int modelIndex) {
128     //int firstAtomDeleted = ((int[])((Object[])value)[2])[1];
129     //int nAtomsDeleted = ((int[])((Object[])value)[2])[2];
130     for (int i = meshCount; --i >= 0;) {
131       CGOMesh m = (CGOMesh) meshes[i];
132       if (m == null)
133         continue;
134       boolean deleteMesh = (m.modelIndex == modelIndex);
135       if (deleteMesh) {
136         meshCount--;
137         deleteMeshElement(i);
138       } else if (meshes[i].modelIndex > modelIndex) {
139         meshes[i].modelIndex--;
140       }
141     }
142     resetObjects();
143    }
144 
145 
146   @Override
getProperty(String property, int index)147   public Object getProperty(String property, int index) {
148     if (property == "command")
149       return getCommand(cgoMesh);
150     return getPropMC(property, index);
151   }
152 
153   @Override
getPropertyData(String property, Object[] data)154   public boolean getPropertyData(String property, Object[] data) {
155     if (property == "data")
156       return CGOMesh.getData(data);
157     return getPropDataMC(property, data);
158   }
159 
deleteMeshElement(int i)160   private void deleteMeshElement(int i) {
161     if (meshes[i] == currentMesh)
162       currentMesh = cgoMesh = null;
163     meshes = cmeshes = (CGOMesh[]) AU
164         .deleteElements(meshes, i, 1);
165   }
166 
setPropertySuper(String propertyName, Object value, BS bs)167   private void setPropertySuper(String propertyName, Object value, BS bs) {
168     currentMesh = cgoMesh;
169     setPropMC(propertyName, value, bs);
170     cgoMesh = (CGOMesh)currentMesh;
171   }
172 
173   @Override
clean()174   protected void clean() {
175     for (int i = meshCount; --i >= 0;)
176       if (meshes[i] == null || cmeshes[i].cmds == null || cmeshes[i].cmds.size() == 0)
177         deleteMeshI(i);
178   }
179 
setCGO(Lst<Object> data)180   private boolean setCGO(Lst<Object> data) {
181     if (cgoMesh == null)
182       allocMesh(null, null);
183     cgoMesh.clear("cgo");
184     return cgoMesh.set(data);
185   }
186 
scale(Mesh mesh, float newScale)187   private void scale(Mesh mesh, float newScale) {
188     // TODO
189 
190   }
191 
192   @Override
getShapeDetail()193   public Object getShapeDetail() {
194     Lst<Map<String, Object>> V = new Lst<Map<String, Object>>();
195     for (int i = 0; i < meshCount; i++) {
196       CGOMesh mesh = cmeshes[i];
197       Map<String, Object> info = new Hashtable<String, Object>();
198       info.put("visible", mesh.visible ? Boolean.TRUE : Boolean.FALSE);
199       info.put("ID", (mesh.thisID == null ? "<noid>" : mesh.thisID));
200       info.put("command", getCommand(mesh));
201       V.addLast(info);
202     }
203     return V;
204   }
205 
206   @Override
getShapeState()207   public String getShapeState() {
208     SB sb = new SB();
209     int modelCount = vwr.ms.mc;
210     for (int i = 0; i < meshCount; i++) {
211       CGOMesh mesh = cmeshes[i];
212       if (mesh == null || mesh.cmds == null || mesh.modelIndex >= modelCount)
213         continue;
214       if (sb.length() == 0) {
215         sb.append("\n");
216         appendCmd(sb, myType + " delete");
217       }
218       sb.append(getCommand2(mesh, modelCount));
219       if (!mesh.visible)
220         sb.append(" " + myType + " ID " + PT.esc(mesh.thisID) + " off;\n");
221     }
222     return sb.toString();
223   }
224 
getCommand(Mesh mesh)225   private String getCommand(Mesh mesh) {
226     if (mesh != null)
227       return getCommand2(mesh, mesh.modelIndex);
228 
229     SB sb = new SB();
230     String key = (explicitID && previousMeshID != null
231         && PT.isWild(previousMeshID) ? previousMeshID : null);
232     Lst<Mesh> list = getMeshList(key, false);
233     // counting down on list will be up in order
234     for (int i = list.size(); --i >= 0;) {
235       Mesh m = list.get(i);
236       sb.append(getCommand2(m, m.modelIndex));
237     }
238     return sb.toString();
239   }
240 
getCommand2(Mesh mesh, int modelCount)241   private String getCommand2(Mesh mesh, int modelCount) {
242     CGOMesh cmesh = (CGOMesh) mesh;
243     SB str = new SB();
244     int iModel = mesh.modelIndex;
245     str.append("  CGO ID ").append(PT.esc(mesh.thisID));
246     if (iModel >= -1 && modelCount > 1)
247       str.append(" modelIndex " + iModel);
248     str.append(" [");
249     int n = cmesh.cmds.size();
250     for (int i = 0; i < n; i++)
251       str.append(" " + cmesh.cmds.get(i));
252     str.append(" ];\n");
253     appendCmd(str, cmesh.getState("cgo"));
254     if (cmesh.useColix)
255       appendCmd(str, getColorCommandUnk("cgo", cmesh.colix, translucentAllowed));
256     return str.toString();
257   }
258 
259   @Override
setModelVisibilityFlags(BS bsModels)260   public void setModelVisibilityFlags(BS bsModels) {
261     for (int i = 0; i < meshCount; i++) {
262       CGOMesh m = cmeshes[i];
263       if (m != null)
264         m.visibilityFlags = (m.isValid && m.visible && (m.modelIndex < 0 || bsModels.get(m.modelIndex)) ? vf : 0);
265     }
266   }
267 
268 }
269