1 package jspecview.dialog;
2 
3 import java.util.Map;
4 
5 import javajs.util.DF;
6 
7 import javajs.util.PT;
8 
9 import jspecview.api.AnnotationData;
10 import jspecview.api.JSVPanel;
11 import jspecview.api.PlatformDialog;
12 import jspecview.common.Annotation;
13 import jspecview.common.Coordinate;
14 import jspecview.common.IntegralData;
15 import jspecview.common.Spectrum;
16 import jspecview.common.JSViewer;
17 import jspecview.common.MeasurementData;
18 import jspecview.common.PanelData;
19 import jspecview.common.Parameters;
20 import jspecview.common.PeakData;
21 
22 abstract public class JSVDialog extends Annotation implements AnnotationData {
23 
getPosXY()24 	abstract public int[] getPosXY();
25 
26 	@Override
isDialog()27 	public boolean isDialog() {
28 	  return true;
29 	}
30 
31 	public String optionKey;
32 	public Map<String, Object> options;
33 
34 	protected AType type;
35 	protected String title;
36 	protected JSViewer vwr;
37 	protected Spectrum spec;
38 	protected DialogManager manager;
39 	protected PlatformDialog dialog;
40 	protected JSVPanel jsvp;
41 	protected Object txt1, txt2, txt3;
42 	protected Object combo1; // measurement listing, peaks
43 	protected MeasurementData xyData;
44 	protected Parameters myParams;
45 	protected int precision = 1;
46 
47 	private int[] loc;
48 	private Object showHideButton; // text changeable
49 	private boolean addClearBtn, addCombo1;
50 	protected boolean addApplyBtn;
51 	private boolean isNumeric; // not Views or OverlayLegend
52 	private boolean defaultVisible; // not OverlayLegend
53 	private String subType;
54 	private String graphSetKey;
55 	private Object[][] tableData;
56 	private boolean addUnits;
57 	private String[] unitOptions;
58 	private int[] formatOptions;
59 	private Integer unitPtr;
60 	private boolean isON = true;
61 
addUniqueControls()62 	abstract protected void addUniqueControls();
63 
callback(String id, String msg)64 	abstract public boolean callback(String id, String msg);
65 
66 	/**
67 	 *
68 	 * required initializer; from JSViewer
69 	 *
70 	 * @param title
71 	 * @param viewer
72 	 * @param spec
73 	 * @return this
74 	 */
setParams(String title, JSViewer viewer, Spectrum spec)75 	public JSVDialog setParams(String title, JSViewer viewer, Spectrum spec) {
76 		title = DialogManager.fixTitle(title);
77 		this.title = title;
78 		this.vwr = viewer;
79 		this.spec = spec;
80 		manager = viewer.getDialogManager();
81 		jsvp = viewer.selectedPanel;
82 		myParams = ((Parameters) viewer.getPlatformInterface("Parameters"))
83 				.setName("dialogParams");
84 		subType = (spec == null ? "!" : spec.getTypeLabel());
85 		optionKey = type + "_" + subType;
86 		options = manager.getDialogOptions();
87 		if (spec != null) {
88 				Object[] specOptions = spec.getDefaultAnnotationInfo(type);
89 			options.put(optionKey, specOptions);
90 			unitOptions = (String[]) specOptions[0];
91 			formatOptions = (int[]) specOptions[1];
92 			unitPtr = (Integer) options.get(optionKey + "_unitPtr");
93 			if (unitPtr == null)
94 				unitPtr = (Integer) specOptions[2];
95 		}
96 		switch (type) {
97 		case Integration:
98 			isNumeric = true;
99 			addClearBtn = true;
100 			defaultVisible = true;
101 			addApplyBtn = true;
102 			break;
103 		case Measurements:
104 			isNumeric = true;
105 			addClearBtn = true;
106 			// no apply button
107 			addCombo1 = true;
108 			defaultVisible = true;
109 			break;
110 		case OverlayLegend:
111 			break;
112 		case PeakList:
113 			isNumeric = true;
114 			addApplyBtn = true;
115 			defaultVisible = true;
116 			break;
117 		case Views:
118 			defaultVisible = true;
119 			break;
120 		case NONE:
121 			break;
122 		}
123 		initDialog();
124 		return this;
125 	}
126 
127 
128 	// //// frame construction ////////
129 
initDialog()130 	private void initDialog() {
131 		dialog = manager.getDialog(this);
132 		restoreDialogPosition(jsvp, getPosXY());
133 		dialog.setTitle(title);
134 		layoutDialog();
135 	}
136 
layoutDialog()137 	protected void layoutDialog() {
138 		dialog.startLayout();
139 		addUniqueControls();
140 		if (isNumeric) {
141 			getUnitOptions();
142 			if (addCombo1)
143 				combo1 = dialog.addSelectOption("cmbUnits", "Units", unitOptions,
144 						unitPtr.intValue(), addUnits);
145 			// txtFontSize = ((DialogHelper dialogHelper)).addInputOption("FontSize",
146 			// "Font Size", null, null, "10");
147 			if (addApplyBtn)
148 				dialog.addButton("btnApply", "Apply");
149 			showHideButton = dialog.addButton("btnShow", "Show");
150 			if (addClearBtn)
151 				dialog.addButton("btnClear", "Clear");
152 		}
153 		dialog.endLayout();
154 		checkEnables();
155 		dialog.setVisible(defaultVisible);
156 	}
157 
158 	/**
159 	 * @param id
160 	 * @param msg
161 	 * @return true if consumed
162 	 */
callbackAD(String id, String msg)163 	protected boolean callbackAD(String id, String msg) {
164 		if (id.equals("FOCUS")) {
165 			eventFocus();
166 		} else if (id.equals("tableSelect")) {
167 			tableSelect(msg);
168 		} else if (id.equals("btnClear")) {
169 			clear();
170 		} else if (id.equals("btnApply")) {
171 			eventApply();
172 		} else if (id.equals("btnShow")) {
173 			String label = dialog.getText(showHideButton);
174 			eventShowHide(label.equals("Show"));
175 		} else if (id.equals("cmbUnits")) {
176 			setPrecision(dialog.getSelectedIndex(combo1));
177 		} else if (id.startsWith("txt")) {
178 			eventApply();
179 		} else if (id.equals("windowClosing")) {
180 			done();
181 			return true;
182 		}
183 		if (jsvp != null)
184 			jsvp.doRepaint(true);
185 		return true;
186 	}
187 
188 	/**
189 	 * @param dialogHelper
190 	 */
addUniqueControls(DialogManager dialogHelper)191 	protected void addUniqueControls(DialogManager dialogHelper) {
192 		// int and peak only
193 	}
194 
195 	// /////// general interface to the outside world ////////
196 
197 	@Override
getAType()198 	public AType getAType() {
199 		return type;
200 	}
201 
202 	@Override
getGraphSetKey()203 	public String getGraphSetKey() {
204 		return graphSetKey;
205 	}
206 
207 	@Override
setGraphSetKey(String key)208 	public void setGraphSetKey(String key) {
209 		this.graphSetKey = key;
210 	}
211 
212 	@Override
getSpectrum()213 	public Spectrum getSpectrum() {
214 		return spec;
215 	}
216 
217 	@Override
getState()218 	public boolean getState() {
219 		return isON;
220 	}
221 
222 	@Override
setState(boolean b)223 	public void setState(boolean b) {
224 		isON = b;
225 	}
226 
227 	// ////// interface to DialogParams////////
228 
checkEnables()229 	public void checkEnables() {
230 		boolean isShow = checkVisible();
231 		dialog.setText(showHideButton, isShow ? "Hide" : "Show");
232 	}
233 
createTable(Object[][] data, String[] header, int[] widths)234 	public void createTable(Object[][] data, String[] header, int[] widths) {
235 		tableData = data;
236 		dialog.createTable(data, header, widths);
237 	}
238 
setTableSelectionEnabled(boolean enabled)239 	public void setTableSelectionEnabled(boolean enabled) {
240 		dialog.setCellSelectionEnabled(enabled);
241 	}
242 
243 	@Override
getParameters()244 	public Parameters getParameters() {
245 		return myParams;
246 	}
247 
showMessage(String msg, String title, int msgType)248 	public void showMessage(String msg, String title, int msgType) {
249 		manager.showMessageDialog(dialog, msg, title, msgType);
250 	}
251 
setThreshold(double y)252 	protected void setThreshold(double y) {
253 		dialog.setText(txt1, getThreasholdText(y));
254 	}
255 
setComboSelected(int i)256 	public void setComboSelected(int i) {
257 		dialog.setSelectedIndex(combo1, i);
258 	}
259 
applyFromFields()260 	public void applyFromFields() {
261 		apply(null);
262 	}
263 
reEnable()264 	public JSVDialog reEnable() {
265 		paramsReEnable();
266 		return this;
267 	}
268 
dispose()269 	public void dispose() {
270 		dialog.dispose();
271 	}
272 
setVisible(boolean visible)273 	public void setVisible(boolean visible) {
274 		dialog.setVisible(visible);
275 	}
276 
277 	@Override
isVisible()278 	public boolean isVisible() {
279 		return dialog.isVisible();
280 	}
281 
selectTableRow(int i)282 	public void selectTableRow(int i) {
283 		dialog.selectTableRow(i);
284 	}
285 
repaint()286 	public void repaint() {
287 		dialog.repaint();
288 	}
289 
setFields()290 	public void setFields() {
291 		switch (type) {
292 		case Integration:
293 			break;
294 		case Measurements:
295 			break;
296 		case NONE:
297 			break;
298 		case PeakList:
299 			myParams = xyData.getParameters();
300 			setThreshold(myParams.peakListThreshold);
301 			setComboSelected(myParams.peakListInterpolation.equals("none") ? 1
302 							: 0);
303 			createData();
304 			break;
305 		case OverlayLegend:
306 			break;
307 		case Views:
308 			break;
309 		}
310 	}
311 
setFocus(boolean tf)312 	public void setFocus(boolean tf) {
313 		dialog.setFocus(tf);
314 	}
315 
update(Coordinate clicked, double xRange, int yOffset)316 	public void update(Coordinate clicked, double xRange, int yOffset) {
317 		selectTableRow(-1);
318 		switch (type) {
319 		case Integration:
320 			loadData();
321 			checkEnables();
322 			break;
323 		case Measurements:
324 			loadData();
325 			checkEnables();
326 			break;
327 		case NONE:
328 			break;
329 		case PeakList:
330 			if (yOffset > 20)
331 				applyFromFields();
332 			if (xyData == null || clicked == null || yOffset > 20)
333 				return;
334 			int ipt = 0;
335 			double dx0 = 1e100;
336 			double xval = clicked.getXVal();
337 			PeakData md = (PeakData) xyData;
338 			double min = Math.abs(xRange / 20);
339 			for (int i = md.size(); --i >= 0;) {
340 				double dx = Math.abs(xval - md.get(i).getXVal());
341 				if (dx < dx0) {
342 					dx0 = dx;
343 					ipt = i;
344 				}
345 			}
346 			if (dx0 < min) {
347 				selectTableRow(md.size() - 2 - ipt);
348 				repaint();
349 			}
350 			break;
351 		case OverlayLegend:
352 			break;
353 		case Views:
354 			break;
355 		}
356 	}
357 
358 	protected double lastNorm = 1;
359 
getPeakData()360 	public MeasurementData getPeakData() {
361 		// could be called by outside, but isn't.
362 		PeakData md = new PeakData(AType.PeakList, spec);
363 		md.setPeakList(myParams, precision, jsvp.getPanelData().getView());
364 		xyData = md;
365 		return null;
366 	}
367 
368 	@Override
getData()369 	public MeasurementData getData() {
370 		if (xyData == null)
371 			createData();
372 		return xyData;
373 	}
374 
setData(AnnotationData data)375 	public void setData(AnnotationData data) {
376 		myParams = data.getParameters();
377 		xyData = (MeasurementData) data;
378 	}
379 
380 	@Override
setSpecShift(double dx)381 	public void setSpecShift(double dx) {
382 		if (xyData != null)
383 			xyData.setSpecShift(dx);
384 	}
385 
setType(AType type)386 	public void setType(AType type) {
387 		this.type = type;
388 		switch (type) {
389 		case Measurements:
390 			addUnits = true;
391 			break;
392 		case Integration:
393 			break;
394 		case PeakList:
395 			break;
396 		case OverlayLegend:
397 			break;
398 		case Views:
399 			break;
400 		case NONE:
401 			break;
402 
403 		}
404 	}
405 
406 	////////////// protected methods
407 
408 	protected int iRowColSelected = -1;
409 	protected int iSelected = -1;
410 
apply(Object[] objects)411 	protected void apply(Object[] objects) {
412 		try {
413 			switch (type) {
414 			case Integration:
415 				double offset = Double.parseDouble((String) objects[0]);
416 				double scale = Double.parseDouble((String) objects[1]);
417 				//double minval = Double.parseDouble((String) objects[2]);
418 				myParams.integralOffset = offset;
419 				myParams.integralRange = scale;
420 				//myParams.integralMinY = minval;
421 				myParams.integralDrawAll = false;
422 				((IntegralData) getData()).update(myParams);
423 				break;
424 			case Measurements:
425 				// n/a
426 				break;
427 			case NONE:
428 				return;
429 			case PeakList:
430 				if (!skipCreate) {
431 					setThreshold(Double.NaN);
432 					createData();
433 				}
434 				skipCreate = false;
435 				break;
436 			case OverlayLegend:
437 				break;
438 			case Views:
439 				vwr.parameters.viewOffset = Double.parseDouble((String) objects[0]);
440 				break;
441 			}
442 			loadData();
443 			checkEnables();
444 			jsvp.doRepaint(true);
445 		} catch (Exception e) {
446 			// ignore
447 		}
448 	}
449 
done()450 	protected void done() {
451 		if (jsvp != null && spec != null)
452 			jsvp.getPanelData().removeDialog(this);
453 		// setState(false);
454 		if (xyData != null)
455 			xyData.setState(isON);
456 		saveDialogPosition(getPosXY());
457 		dispose();
458 		jsvp.doRepaint(true);
459 	}
460 
461 
462 	// /////////// private methods
463 
464 	/**
465 	 *
466 	 * @param panel
467 	 *          a PPanel (Applet) or a JScrollPane (MainFrame)
468 	 *
469 	 * @param posXY
470 	 *          static for a given dialog
471 	 */
restoreDialogPosition(JSVPanel panel, int[] posXY)472 	private void restoreDialogPosition(JSVPanel panel, int[] posXY) {
473 		if (panel != null) {
474 			if (posXY[0] == Integer.MIN_VALUE) {
475 				posXY[0] = 0;
476 				posXY[1] = -20;
477 			}
478 			int[] pt = manager.getLocationOnScreen(panel);
479 			int height = panel.getHeight();
480 			loc = new int[] { Math.max(0, pt[0] + posXY[0]),
481 					Math.max(0, pt[1] + height + posXY[1]) };
482 			dialog.setIntLocation(loc);
483 		}
484 	}
485 
saveDialogPosition(int[] posXY)486 	private void saveDialogPosition(int[] posXY) {
487 		try {
488 			int[] pt = manager.getLocationOnScreen(dialog);
489 			posXY[0] += pt[0] - loc[0];
490 			posXY[1] += pt[1] - loc[1];
491 		} catch (Exception e) {
492 			// ignore
493 		}
494 	}
495 
getThreasholdText(double y)496 	private String getThreasholdText(double y) {
497 		if (Double.isNaN(y)) {
498 			PanelData pd = jsvp.getPanelData();
499 			double f = (pd.getSpectrum().isInverted() ? 0.1 : 0.9);
500 			Coordinate c = pd.getClickedCoordinate();
501 			y = (c == null ? (pd.getView().minYOnScale * f + pd.getView().maxYOnScale)
502 					* (1 - f)
503 					: c.getYVal());
504 		}
505 		String sy = DF.formatDecimalDbl(y, y < 1000 ? 2 : -2); // "#0.00" :
506 		// "0.00E0"
507 		return " " + sy;
508 	}
509 
checkVisible()510 	private boolean checkVisible() {
511 		return vwr.pd().getShowAnnotation(type);
512 	}
513 
getUnitOptions()514 	private void getUnitOptions() {
515 		String key = optionKey + "_format";
516 		Integer format = (Integer) options.get(key);
517 		if (format == null)
518 			options.put(key, format = Integer
519 					.valueOf(formatOptions[unitPtr == null ? 0 : unitPtr.intValue()]));
520 		// txtFormat = dialogHelper.addInputOption("numberFormat", "Number Format",
521 		// format, null, null, false);
522 	}
523 
524 	private boolean skipCreate;
525 
eventFocus()526 	protected void eventFocus() {
527 		if (spec != null)
528 			jsvp.getPanelData().jumpToSpectrum(spec);
529 		switch (type) {
530 		case Integration:
531 			if (iRowSelected >= 0) {
532 				iRowSelected++;
533 				tableCellSelect(-1, -1);
534 			}
535 			break;
536 		case Measurements:
537 			break;
538 		case NONE:
539 			break;
540 		case PeakList:
541 			createData();
542 			skipCreate = true;
543 			break;
544 		case OverlayLegend:
545 			break;
546 		case Views:
547 			break;
548 		}
549 	}
550 
eventApply()551 	protected void eventApply() {
552 		switch (type) {
553 		case Integration:
554 			break;
555 		case Measurements:
556 			break;
557 		case NONE:
558 			break;
559 		case PeakList:
560 			createData();
561 			skipCreate = true;
562 			break;
563 		case OverlayLegend:
564 			break;
565 		case Views:
566 			break;
567 		}
568 		applyFromFields();
569 	}
570 
eventShowHide(boolean isShow)571 	private void eventShowHide(boolean isShow) {
572 		isON = isShow;
573 		if (isShow)
574 			eventApply();
575 		jsvp.doRepaint(true);
576 		checkEnables();
577 	}
578 
clear()579 	private void clear() {
580 		setState(true);
581 		if (xyData != null) {
582 			xyData.clear();
583 			applyFromFields();
584 		}
585 	}
586 
paramsReEnable()587 	private void paramsReEnable() {
588 		switch (type) {
589 		case Integration:
590 			break;
591 		case Measurements:
592 			break;
593 		case NONE:
594 			break;
595 		case PeakList:
596 			skipCreate = true;
597 			break;
598 		case OverlayLegend:
599 			break;
600 		case Views:
601 			break;
602 		}
603 		setVisible(true);
604 		isON = true;
605 		applyFromFields();
606 	}
607 
608 	private int iRowSelected = -1;
609 	private int iColSelected = -1;
610 
tableCellSelect(int iRow, int iCol)611 	private void tableCellSelect(int iRow, int iCol) {
612 		System.out.println(iRow + " jSVDial " + iCol);
613 		if (iRow < 0) {
614 			iRow = iRowColSelected / 1000;
615 			iCol = iRowColSelected % 1000;
616 			iRowColSelected = -1;
617 		}
618 		Object value = tableData[iRow][1];
619 		int icolrow = iRow * 1000 + iCol;
620 		if (icolrow == iRowColSelected)
621 			return;
622 		iRowColSelected = icolrow;
623 		System.out.println("Setting rc = " + iRowColSelected + " " + spec);
624 		selectTableRow(iRowSelected);
625 		try {
626 			switch (type) {
627 			case Integration:
628 				callback("SHOWSELECTION", value.toString());
629 				checkEnables();
630 				break;
631 			case Measurements:
632 				break;
633 			case NONE:
634 				break;
635 			case PeakList:
636 				try {
637 					switch (iCol) {
638 					case 6:
639 					case 5:
640 					case 4:
641 						double x1 = Double.parseDouble((String) value);
642 						double x2 = Double
643 								.parseDouble((String) tableData[iRow + 3 - iCol][1]);
644 						jsvp.getPanelData().setXPointers(spec, x1, spec, x2);
645 						break;
646 					default:
647 						jsvp.getPanelData().findX(spec, Double.parseDouble((String) value));
648 					}
649 				} catch (Exception e) {
650 					jsvp.getPanelData().findX(spec, 1E100);
651 				}
652 				jsvp.doRepaint(false);
653 				break;
654 			case OverlayLegend:
655 				jsvp.getPanelData().setSpectrum(iRow, false);
656 				break;
657 			case Views:
658 				break;
659 			}
660 		} catch (Exception e) {
661 			// for parseDouble
662 		}
663 	}
664 
loadData()665 	protected void loadData() {
666 		Object[][] data;
667 		String[] header;
668 		int[] widths;
669 		switch (type) {
670 		case Integration:
671 			if (xyData == null)
672 				createData();
673 			iSelected = -1;
674 			data = ((IntegralData) xyData).getMeasurementListArray(null);
675 			header = xyData.getDataHeader();
676 			widths = new int[] { 40, 65, 65, 50 };
677 			createTable(data, header, widths);
678 			break;
679 		case Measurements:
680 			if (xyData == null)
681 				return;
682 			data = xyData.getMeasurementListArray(dialog.getSelectedItem(combo1).toString());
683 			header = xyData.getDataHeader();
684 			widths = new int[] { 40, 65, 65, 50 };
685 			createTable(data, header, widths);
686 			break;
687 		case NONE:
688 			break;
689 		case PeakList:
690 			if (xyData == null)
691 				createData();
692 			data = ((PeakData) xyData).getMeasurementListArray(null);
693 			header = ((PeakData) xyData).getDataHeader();
694 			widths = new int[] { 40, 65, 50, 50, 50, 50, 50 };
695 			createTable(data, header, widths);
696 			setTableSelectionEnabled(true);
697 			break;
698 		case OverlayLegend:
699 			header = new String[] { "No.", "Plot Color", "Title" };
700 			data = vwr.selectedPanel.getPanelData().getOverlayLegendData();
701 			widths = new int[] { 30, 60, 250 };
702 			createTable(data, header, widths);
703 			setTableSelectionEnabled(true);
704 			break;
705 		case Views:
706 			break;
707 		}
708 	}
709 
createData()710 	private void createData() {
711 		switch (type) {
712 		case Integration:
713 			xyData = new IntegralData(spec, myParams);
714 			iSelected = -1;
715 			break;
716 		case Measurements:
717 			// n/a
718 			break;
719 		case NONE:
720 			break;
721 		case PeakList:
722 			try {
723 				double thresh = Double.parseDouble(dialog.getText(txt1));
724 				myParams.peakListThreshold = thresh;
725 				myParams.peakListInterpolation = dialog.getSelectedItem(combo1)
726 						.toString();
727 				myParams.precision = precision;
728 				PeakData md = new PeakData(AType.PeakList, spec);
729 				md.setPeakList(myParams, precision, jsvp.getPanelData().getView());
730 				xyData = md;
731 				loadData();
732 			} catch (Exception e) {
733 				// for parseDouble
734 			}
735 			break;
736 		case OverlayLegend:
737 			break;
738 		case Views:
739 			break;
740 		}
741 	}
742 
setPrecision(int i)743 	private void setPrecision(int i) {
744 		precision = formatOptions[i];
745 	}
746 
tableSelect(String url)747 	private void tableSelect(String url) {
748 		boolean isAdjusting = "true".equals(getField(url, "adjusting"));
749 		if (isAdjusting) {
750 			iColSelected = iRowSelected = -1;
751 			System.out.println("adjusting" + url);
752 			return;
753 		}
754 		int index = PT.parseInt(getField(url, "index"));
755 		switch ("ROW COL ROWCOL".indexOf(getField(url, "selector"))) {
756 		case 8:
757 			iColSelected = PT.parseInt(getField(url, "index2"));
758 			//$FALL-THROUGH$
759 		case 0:
760 			iRowSelected = index;
761 			System.out.println("r set to " + index);
762 			break;
763 		case 4:
764 			iColSelected = index;
765 			System.out.println("c set to " + index);
766 			break;
767 		}
768 		if (iColSelected >= 0 && iRowSelected >= 0) {
769 			tableCellSelect(iRowSelected, iColSelected);
770 		}
771 	}
772 
getField(String url, String name)773 	private String getField(String url, String name) {
774 		url += "&";
775 		String key = "&" + name + "=";
776 		int pt = url.indexOf(key);
777 		return (pt < 0 ? null : url.substring(pt + key.length(), url.indexOf("&",
778 				pt + 1)));
779 	}
780 
781 
782 }
783