001    /*
002     * Created by IntelliJ IDEA.
003     * User: Wei Wang
004     * Date: 2002-9-6
005     * Time: 15:53:41
006     * To change template for new class use 
007     * Code Style | Class Templates options (Tools | IDE Options).
008     */
009    package EVolve.util;
010    
011    import EVolve.visualization.*;
012    import EVolve.visualization.XYViz.XYVisualization;
013    import EVolve.visualization.XYViz.RefRefViz.ReferenceReferenceVisualization;
014    import EVolve.Scene;
015    import EVolve.data.*;
016    import javax.swing.*;
017    import javax.swing.filechooser.FileSystemView;
018    import java.awt.*;
019    import java.awt.event.*;
020    import java.io.*;
021    import java.util.*;
022    
023    public class AsynchronousOverlapper extends OverlapVisualization {
024        private final String name = "AsynchronousOverlapper";
025        private JList fileList,procList;
026        private JTextField txtConfName;
027        private HashSet setFile;
028        private ArrayList setProcessFiles;
029        private DefaultListModel procListModel,fileListModel;
030        private ArrayList[] entityList;
031    
032        public AsynchronousOverlapper() {
033            super();
034            dialog = null;
035            setProcessFiles = new ArrayList();
036            setFile = new HashSet();
037            colorList = new ArrayList();
038            entityList = new ArrayList[2];
039            entityList[0] = new ArrayList();
040            entityList[1] = new ArrayList();
041        }
042    
043        public String getName() {
044            return name;
045        }
046    
047        public void createDialog() {
048            setFile.clear();
049            setProcessFiles.clear();
050            colorList.clear();
051            visualizationList.clear();
052            dialog = new JDialog(Scene.getFrame(),"Overlap Visualizations...",true);
053            dialog.setBounds(new Rectangle(500,400));
054    
055            JPanel batchName = new JPanel(new FlowLayout());
056            dialog.getContentPane().add(batchName,BorderLayout.NORTH);
057    
058            Box boxMain = new Box(BoxLayout.Y_AXIS);
059            boxMain.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
060                    "Choose data source(s) to be overlapped & Processing configuration"));
061            dialog.getContentPane().add(boxMain,BorderLayout.CENTER);
062    
063    
064            Box boxLabels = new Box(BoxLayout.X_AXIS);
065            JButton buttonGetDir = new JButton("Select Directory ..");
066            buttonGetDir.addActionListener(new ActionListener(){
067                public void actionPerformed(ActionEvent e){
068                        fillFileList();
069                }
070            });
071            boxLabels.add(buttonGetDir);
072            boxLabels.add(Box.createHorizontalGlue());
073            boxLabels.add(new JLabel("Processing List                             "));
074    
075            Box boxLists = new Box(BoxLayout.X_AXIS);
076            fileListModel = new DefaultListModel();
077            fileList = new JList(fileListModel);
078    
079            Box boxAddRemove = new Box(BoxLayout.Y_AXIS);
080            JButton buttonAdd = new JButton("  >  ");
081            buttonAdd.addActionListener(new ActionListener(){
082                public void actionPerformed(ActionEvent e){
083                    addFiles();
084                }
085            });
086            JButton buttonRemove = new JButton("  <  ");
087            buttonRemove.addActionListener(new ActionListener(){
088                public void actionPerformed(ActionEvent e){
089                    removeFiles();
090                }
091            });
092            boxAddRemove.add(Box.createVerticalStrut(40));
093            boxAddRemove.add(buttonAdd);
094            boxAddRemove.add(Box.createVerticalStrut(20));
095            boxAddRemove.add(buttonRemove);
096    
097            procListModel = new DefaultListModel();
098            procList = new JList(procListModel);
099    
100            JScrollPane scrollPane1 = new JScrollPane(fileList);
101            JScrollPane scrollPane2 = new JScrollPane(procList);
102            boxLists.add(scrollPane1);
103            boxLists.add(boxAddRemove);
104            boxLists.add(scrollPane2);
105    
106            boxMain.add(boxLabels);
107            boxMain.add(Box.createVerticalStrut(5));
108            boxMain.add(boxLists);
109    
110            Box boxConfig = new Box(BoxLayout.X_AXIS);
111            boxConfig.add(new JLabel("Choose configure file:"));
112            txtConfName = new JTextField(12);
113            boxConfig.add(Box.createHorizontalStrut(20));
114            boxConfig.add(txtConfName,BorderLayout.CENTER);
115            JButton buttonConfig = new JButton("...");
116            buttonConfig.addActionListener(new ActionListener(){
117                public void actionPerformed(ActionEvent e){
118                    txtConfName.setText(chooseConfig());
119                }
120            });
121            boxConfig.add(buttonConfig,BorderLayout.EAST);
122    
123            Box boxOkCancel = new Box(BoxLayout.X_AXIS);
124            JButton buttonOK = new JButton("OK");
125            JButton buttonCancel = new JButton("Cancel");
126            JButton buttonColor = new JButton("Coloring");
127    
128            buttonOK.addActionListener(new ActionListener(){
129                public void actionPerformed(ActionEvent e){
130                    onOK();
131                }
132            });
133            buttonCancel.addActionListener(new ActionListener(){
134                public void actionPerformed(ActionEvent e){
135                    onCancel();
136                }
137            });
138            buttonColor.addActionListener(new ActionListener(){
139                public void actionPerformed(ActionEvent e){
140                    selectColor();
141                }
142            });
143    
144            boxOkCancel.add(Box.createHorizontalStrut(25));
145            boxOkCancel.add(buttonColor);
146            boxOkCancel.add(Box.createHorizontalStrut(20));
147            boxOkCancel.add(buttonOK);
148            boxOkCancel.add(Box.createHorizontalStrut(20));
149            boxOkCancel.add(buttonCancel);
150    
151            Box boxBottom = Box.createVerticalBox();
152            boxBottom.add(Box.createVerticalStrut(12));
153            boxBottom.add(boxConfig);
154            boxBottom.add(Box.createVerticalStrut(30));
155            boxBottom.add(boxOkCancel);
156    
157    
158            dialog.getContentPane().add(boxBottom,BorderLayout.SOUTH);
159            //dialog.setResizable(false);
160    
161        }
162    
163        private void selectColor() {
164            int index = procList.getSelectedIndex();
165    
166            if (index != -1) {
167                Color newColor = JColorChooser.showDialog(Scene.getFrame(), "Choose a color", Color.black);
168                if (newColor != null) {
169                    colorList.add(index,newColor);
170                    colorList.remove(index+1);
171                    procListModel.removeAllElements();
172    
173                    for (int i=0; i<setProcessFiles.size(); i++) {
174                        if (colorList.get(i) == null)
175                            procListModel.addElement(setProcessFiles.get(i));
176                        else
177                            procListModel.addElement("<html><font color=#" + getColorHex((Color)colorList.get(i)) + ">"
178                                                 + setProcessFiles.get(i) +" </font></html>" );
179                    }
180                }
181            }
182        }
183    
184        private void onOK() {
185    
186            if (procListModel.size() < 2) {
187               Scene.showErrorMessage("Please select at least 2 data source.");
188               return;
189            }
190    
191            if (txtConfName.getText().trim().length() == 0) {
192                Scene.showErrorMessage("No configuration file selected!");
193                return;
194            }
195            dialog.setVisible(false);
196            noEntityAvailable = false;
197    
198            overlappedVisualize();
199        }
200    
201        private void onCancel() {
202            dialog.setVisible(false);
203        }
204    
205        private void addFiles() {
206            int[] selectIndex = fileList.getSelectedIndices();
207            ArrayList newColorList = new ArrayList();
208    
209            for (int i=0;i<selectIndex.length;i++) {
210                if (setProcessFiles.contains(fileListModel.getElementAt(selectIndex[i]))) continue;
211    
212                setProcessFiles.add(fileListModel.getElementAt(selectIndex[i]));
213                procListModel.addElement(fileListModel.getElementAt(selectIndex[i]));
214            }
215    
216            for (int i=0; i<setProcessFiles.size();i++) {
217                if (i<colorList.size())
218                    newColorList.add(i,colorList.get(i));
219                else
220                    newColorList.add(i,null);
221            }
222            colorList = newColorList;
223        }
224    
225        private void removeFiles() {
226            int[] selectIndex = procList.getSelectedIndices();
227    
228            for (int i=selectIndex.length -1 ;i>=0;i--) {
229                setProcessFiles.remove(selectIndex[i]);
230                colorList.remove(selectIndex[i]);
231                procListModel.removeElement(procListModel.getElementAt(selectIndex[i]));
232            }
233        }
234    
235        private String chooseConfig() {
236            JFileChooser fc = new JFileChooser(Scene.getUIManager().getLastConfigDir());
237    
238            if(fc.showOpenDialog(Scene.getFrame()) == JFileChooser.APPROVE_OPTION) {
239                File f = fc.getSelectedFile();
240                Scene.getUIManager().setLastConfigDir(f.getPath());
241                return (f.getPath());
242            }
243            else return "";
244        }
245    
246        private void fillFileList() {
247            JFileChooser fc = new JFileChooser(Scene.getUIManager().getLastDataDir());
248            String path;
249    
250            fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
251    
252            fileListModel.removeAllElements();
253            if(fc.showOpenDialog(Scene.getFrame()) == JFileChooser.APPROVE_OPTION) {
254                path = fc.getSelectedFile().getAbsolutePath();
255                Scene.getUIManager().setLastDataDir(path);
256                File dir = new File(path);
257                FileSystemView fv = fc.getFileSystemView();
258                File[] fl = fv.getFiles(dir,false);
259                for (int i=0;i<fl.length;i++) {
260                    String fn = fl[i].getName();
261                    if (!fl[i].isFile() || !fn.endsWith(".dat") || setFile.contains(path+File.separator+fn))
262                        continue;
263                    setFile.add(path+File.separator+fn);
264                    fileListModel.addElement(path+File.separator+fn);
265                }
266            }
267    
268        }
269    
270        public boolean isOverlapable(Visualization visualToBeOverlapped) {
271            return true;
272        }
273    
274        public void preOverlappedVisualize() {
275            RandomAccessFile inConfigFile;
276            String dataSource;
277            VizInfo vizInfo = null;
278            String dimensionDefs[] = new String[3];
279            String factoryName,subjectName,predictor,interval;
280            HashMap mapConfig = new HashMap();
281            Visualization visual;
282    
283            reset();
284            try {
285                inConfigFile = new RandomAccessFile(txtConfName.getText().trim(), "r");
286                String version = inConfigFile.readLine().trim();
287                if (!version.equals(Scene.VERSION)) throw (new IOException());
288                inConfigFile.readLine();
289                factoryName = inConfigFile.readLine().trim();
290                subjectName = inConfigFile.readLine().trim();
291                for (int j=0;j<dimensionDefs.length;j++) {
292                    dimensionDefs[j] = inConfigFile.readLine().trim();
293                }
294                predictor = inConfigFile.readLine().trim();
295                interval = inConfigFile.readLine().trim();
296                inConfigFile.close();
297                for (int i=0; i<procListModel.size(); i++) {
298                    dataSource = (String)setProcessFiles.get(i);
299                    Scene.setDataFilename(dataSource);
300                    Scene.autoLoadDataSource();
301    
302                    vizInfo = new VizInfo();
303                    vizInfo.createFactory(factoryName);
304                    vizInfo.createSubjectDefinition(subjectName);
305                    vizInfo.createDimension(dimensionDefs);
306                    vizInfo.createPredictor(predictor);
307                    vizInfo.createInterval(interval);
308                    vizInfo.createTitle(dataSource);
309                    for (int k=0; k< entityList.length; k++)
310                        if (vizInfo.getDimension()[k] instanceof ReferenceDimension)
311                            entityList[k].add(Scene.getDataManager().getEntity()[vizInfo.getDimension()[k].getDataFilter().getTargetType()]);
312    
313                    mapConfig.put("Factory",vizInfo.getFactory());
314                    mapConfig.put("Subject",vizInfo.getSubject());
315                    mapConfig.put("Dimension",vizInfo.getDimension());
316                    mapConfig.put("Predictor",vizInfo.getPredictor());
317                    mapConfig.put("Interval",new Integer(vizInfo.getInterval()));
318                    mapConfig.put("BeginCall",new Integer(vizInfo.getBeginCall()));
319                    mapConfig.put("EndCall",new Integer(vizInfo.getEndCall()));
320    
321                    visual = Scene.getVisualizationManager().newVisualization(((VisualizationFactory)mapConfig.get("Factory")).getName());
322    
323                    visual.setName(vizInfo.getTitle());
324                    visual.autoUpdateConfiguration(mapConfig);
325                    visualizationList.add(visual);
326    
327                    Scene.getVisualizationManager().addAllVisualizations();
328                    Scene.getVisualizationManager().prepareListToBeVisualized();
329                    Scene.autoVisualize();
330    
331                }
332            } catch (Exception e) {
333                System.out.println("Configure file error!");
334            }
335        }
336    
337        public void overlappedVisualize() {
338            Visualization visual;
339    
340            Scene.getVisualizationManager().init();
341            Scene.getUIManager().init();
342    
343            if (window instanceof EVolve.Window) {
344                Scene.getUIManager().removeWindow(window);
345                window = null;
346            }
347            visualizationList.clear();
348            Scene.getUIManager().setDoNotRemoveWindow(true);
349            preOverlappedVisualize();
350            Scene.getUIManager().setDoNotRemoveWindow(false);
351            Scene.setDataFilename(null);
352    
353    
354            unifyVisualizations();
355    
356            // begin drawing overlap
357            if (window instanceof EVolve.Window) {
358                Scene.getUIManager().removeWindow(window);
359                window = null;
360            }
361    
362            newOverlappedVisualization(this);
363    
364            int [] selectedIndex = new int[2];
365            int [] sortedDimension = new int[2];
366            visual = (Visualization)visualizationList.get(0);
367    
368            for (int i=0; i<maxEntity.length; i++) {
369                if (visual.getDimension()[i] instanceof ReferenceDimension) {
370    
371                    selectedIndex[i] = ((ReferenceDimension)visual.getDimension()[i]).getSelectedComparatorIndex();
372                    sortedDimension[i] = 1;
373                    break;
374                }
375            }
376    
377            sort();
378            enableSortMenu();
379        }
380    
381        private void unifyVisualizations() {
382            // now we begin unify all entities
383            ArrayList standard[] = new ArrayList[2];
384            standard[0] = new ArrayList();
385            standard[1] = new ArrayList();
386            ArrayList posMapList[] = new ArrayList[2];
387            posMapList[0] = new ArrayList();
388            posMapList[1] = new ArrayList();
389            // initial the max entity to visualization 0's entity
390            for (int i=0; i<entityList.length; i++) {
391                Entity[] temp;
392                if (entityList[i].size() !=0 ) {
393                    temp = (Entity[])entityList[i].get(0);
394                    HashMap map = new HashMap();
395                    for (int j=0; j<temp.length; j++) {
396                        standard[i].add(temp[j]);
397                        map.put(new Integer(j),new Integer(j));
398                    }
399                    posMapList[i].add(map);
400    
401                } else
402                    continue;
403            }
404    
405            for (int i=0; i<entityList.length; i++) {
406                for (int j=1; j<entityList[i].size(); j++) {
407                    HashMap map = unifyEntities(standard[i], (Entity[])entityList[i].get(j));
408                    posMapList[i].add(map);
409                }
410            }
411            // dump the unified entity to an array
412            for (int i=0; i<standard.length; i++) {
413                if (standard[i].size() == 0) continue;
414                maxEntity[i] = new Entity[standard[i].size()];
415                for (int j=0; j<standard[i].size(); j++) {
416                    maxEntity[i][j] = (Entity)standard[i].get(j);
417                }
418            }
419            // unifying entity done here, begin to update ordering information in all visualizations
420    
421            // update ordering information begins
422            Visualization visual;
423            for (int i=0; i<entityList.length; i++) {
424                if (entityList[i].size() == 0) continue; // not a reference dimension
425                for (int j=0; j<visualizationList.size(); j++) {
426                    visual = (Visualization)visualizationList.get(j);
427                    AutoImage newImage;
428    
429                    ReferenceDimension dim = visual.getLinkableDimension(i);
430                    // reorganize the image data here
431                    Color newColor = (Color)colorList.get(j);
432                    AutoImage image = visual.getImage();
433                    if (i == 0) {
434                        newImage = switchColor(image,(HashMap)posMapList[i].get(j),newColor,false);
435                    } else {
436                        newImage = switchColor(image,(HashMap)posMapList[i].get(j),newColor,true);
437                    }
438    
439                    if (newImage!=null) visual.setImage(newImage);
440    
441                    // reorganize the image data ends
442                    int[] order = updateOrdering(maxEntity[i],(HashMap)posMapList[i].get(j),dim.getOrdering());
443                    dim.setOrdering(order);
444                    dim.linkEntities(maxEntity[i]);
445                    dim.visualize();
446                    ((XYVisualization)visual).disablePopupMenu();
447                }
448            }
449    
450            for (int i=0; i<visualizationList.size(); i++) {
451                visual = (Visualization)visualizationList.get(i);
452                if (!(visual instanceof ReferenceReferenceVisualization))
453                    break;
454    
455                int[][] newValue = new int[maxEntity[0].length][maxEntity[1].length];
456                switchValues((ReferenceReferenceVisualization)visual,newValue,posMapList[i]);
457            }
458            // update ordering information ends
459        }
460    
461        private AutoImage switchColor(AutoImage image, HashMap positionMap,Color newColor, boolean rowSwitch) {
462            int w = image.getW();
463            int h = image.getH();
464            int end = rowSwitch ? h : w;
465            AutoImage returnVal = new AutoImage();
466    
467            if (positionMap == null) return null;
468            for (int oldPos=0; oldPos<end; oldPos++) {
469                int newPos = ((Integer)positionMap.get(new Integer(oldPos))).intValue();
470                int end2 = rowSwitch ? w : h;
471                for (int k=0; k<end2; k++) {
472                    Color tempColor = null;
473                    if (rowSwitch) {
474                        tempColor = image.getColor(k,oldPos);
475                        if (tempColor == null) continue;
476                        if (newColor != null) tempColor = newColor;
477                        returnVal.setColor(k,newPos,tempColor);
478                    } else {
479                        tempColor = image.getColor(oldPos,k);
480                        if (tempColor == null) continue;
481                        if (newColor != null) tempColor = newColor;
482                        returnVal.setColor(newPos,k,tempColor);
483    
484                    }
485                }
486            }
487            return returnVal;
488        }
489    
490        private void switchValues(ReferenceReferenceVisualization visual, int[][] newValue, ArrayList positionMap) {
491            int[][] oldValue = visual.getValue();
492    
493            for (int i=0; i<positionMap.size(); i++) {
494                HashMap map = (HashMap)positionMap.get(i);
495                if (i == 0) {
496                    for (int j=0; j<oldValue[0].length; j++) {
497                        if (!map.containsKey(new Integer(j))) continue;
498                        int newPos = ((Integer)map.get(new Integer(j))).intValue();
499                        for (int k=0; k<oldValue.length; k++) {
500                            newValue[k][newPos] = oldValue[k][j];
501                        }
502                    }
503                } else {
504                    oldValue = null;
505                    oldValue = new int[newValue.length][newValue[0].length];
506                    for (int j=0; j<oldValue.length; j++) {
507                        if (!map.containsKey(new Integer(j))) continue;
508                        int newPos = ((Integer)map.get(new Integer(j))).intValue();
509                        for (int k=0; k<oldValue[0].length; k++) {
510                            oldValue[newPos][k] = newValue[j][k];
511                        }
512                    }
513                }
514            }
515    
516            visual.setValue(oldValue);
517        }
518    
519        private HashMap unifyEntities(ArrayList standard, Entity[] toBeUnified) {
520            int oldPosition, stdPosition,appendPosition = standard.size();
521            ArrayList tobeAdded = new ArrayList();
522            HashMap positionMap = new HashMap();
523    
524    
525    
526            for (oldPosition = 0; oldPosition < toBeUnified.length; oldPosition++) {
527                boolean found = false;
528                for (stdPosition = 0; stdPosition < standard.size(); stdPosition++) {
529                    if (((Entity)standard.get(stdPosition)).getName().equals(toBeUnified[oldPosition].getName())) {
530                        found = true;
531                        positionMap.put(new Integer(oldPosition),new Integer(stdPosition));
532                        break;
533                    }
534                }
535                if (!found) {
536                    tobeAdded.add(toBeUnified[oldPosition]);
537                    positionMap.put(new Integer(oldPosition), new Integer(appendPosition));
538                    appendPosition++;
539                }
540            }
541    
542            for (int i=0; i<tobeAdded.size(); i++) {
543                standard.add(tobeAdded.get(i));
544            }
545    
546            return positionMap;
547        }
548    
549        private int[] updateOrdering(Entity[] standard, HashMap positionMap, int[] oldOrder) {
550            int newOrder[] = new int[standard.length];
551    
552    
553            for (int i=0; i<newOrder.length; i++) {
554                newOrder[i] = Integer.MAX_VALUE;
555            }
556    
557            if (positionMap == null) {
558                for (int i=0; i<oldOrder.length; i++)
559                    newOrder[i] = oldOrder[i];
560                return newOrder;
561            }
562    
563            Iterator it = positionMap.keySet().iterator();
564    
565            while (it.hasNext()) {
566                Integer oldPosition = (Integer)it.next();
567                Integer newPosition = (Integer)positionMap.get(oldPosition);
568    
569                newOrder[newPosition.intValue()] = oldOrder[oldPosition.intValue()];
570            }
571    
572            return newOrder;
573        }
574    
575        private void reset() {
576            maxEntity[0] = null;
577            maxEntity[1] = null;
578            for (int i= 0; i<entityList.length ; i++) {
579                entityList[i].clear();
580            }
581        }
582    }