Newer
Older
PureATN_M / src / main / java / cit / PureATN / PenUser.java
package cit.PureATN;

import java.awt.Color;
import java.awt.Graphics;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import org.piccolo2d.PNode;
import org.piccolo2d.util.PObjectOutputStream;

public class PenUser implements Serializable {
	private static final long serialVersionUID = 9212314123123L;
	public static Hashtable<String, PenUser> penusers = new Hashtable<String, PenUser>();

	public enum GraphicsMode {
		Piccolo2D,
		AWT;
	}

	// Piccoloをつかうか、AWTをつかうか選択する
	public static GraphicsMode graphicsMode = GraphicsMode.Piccolo2D;

	/**
	 * DPenReceiverから呼ばれる。penIDに対応した、PenUserのインスタンスを返す(なければ用意する)
	 * 
	 * @param penid
	 */
	public static PenUser find(String penid) {
		penid = penid.trim();
		PenUser pu = penusers.get(penid);
		if (pu == null) {
			pu = new PenUser(penid, Note.theapp);
			penusers.put(penid, pu);
		}
		return pu;
	}

	/**
	 * DPenReceiverから呼ばれる。penIDごとに、PenUserのインスタンスを用意している
	 * 
	 * @param penid
	 * @param x
	 * @param y
	 */
	public static void add(String penid, int x, int y) {
		PenUser pu = PenUser.find(penid);
		pu.add(x, y);
	}

	public static void press(String penid, int phase, boolean realPen) {
		PenUser pu = PenUser.find(penid);
		pu.press(phase, realPen);
	}

	public static void drawAll(Graphics g) {
		for (PenUser pu : penusers.values()) {
			pu.draw(g);
		}
	}

	public static void saveToFile(String fn, byte[] ba) {
		if (fn == null)
			fn = "output.patn";
		FileReadWriter.writeBytesToFile(fn, ba);
	}

	public static byte[] loadFromFile(String fn) {
		if (fn == null)
			fn = "output.patn";
		byte[] ba = FileReadWriter.readBytesFromFile(fn);
		// byteSerializeImport(ba);
		return ba;
	}

	public static byte[] byteSerializeExport() {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		OutputStream gzipos = null;
		PObjectOutputStream pobjos = null; // PNodeを保存するときはPObjectOutputStream

		try {
			gzipos = new GZIPOutputStream(baos);
			pobjos = new PObjectOutputStream(gzipos);
			// pobjos.writeObjectTree(penusers);

			pobjos.writeInt(penusers.size());
			Collection<PenUser> ite = PenUser.penusers.values();
			for (PenUser pu : ite) {
				pobjos.writeObjectTree(pu);
			}
			// pobjos.writeObject(penusers);
			pobjos.close();
			gzipos.close();
		} catch (IOException iex) {
			iex.printStackTrace(System.out);
		}
		System.out.println("save size: " + baos.size() + " bytes.");
		return baos.toByteArray();
	}

	public static void byteSerializeImport(byte[] ba) {
		ByteArrayInputStream bais = new ByteArrayInputStream(ba);
		InputStream gzipis = null;
		ObjectInputStream ois = null;
		PNode pn = null;
		try {
			gzipis = new GZIPInputStream(bais);
			ois = new ObjectInputStream(gzipis);

			int numofpenuser = ois.readInt();
			for (int i = 0; i < numofpenuser; i++) {
				PenUser tmp = (PenUser) ois.readObject();
				tmp.restore();
			}
			ois.close();
			gzipis.close();
			bais.close();
		} catch (EOFException eofex) {
			eofex.printStackTrace();
		} catch (IOException excep) {
			excep.printStackTrace(System.err);
		} catch (ClassNotFoundException excnf) {
			System.err.println("ClassNotFound Error");
		} finally {
		}
	}

	private void restore() {
		System.out.println("restore penid " + penid);
		System.out.println("count " + strokes.size());
		penusers.put(penid, this);
		for (ShortStroke squiggle : strokes) {
			squiggle.rebuildStroke();
			squiggle.restore_on_load();
		}
		Note.theapp.repaint();

	}

	// オブジェクトごとのフィールド
	String penid;
	ArrayList<Stroke> stockstrks; // Java AWT/Swing Graphics用
	public ArrayList<ShortStroke> strokes; // Piccolo2D用
	Stroke lastStroke = null;
	ShortStroke squiggle = null; // for Note View
	transient Note parent;
	int num = 0;

	public PenUser(String pid, Note _parent) {
		parent = _parent;
		penid = pid;
		if (graphicsMode == GraphicsMode.AWT) {
			stockstrks = new ArrayList<Stroke>();
		} else {
			strokes = new ArrayList<ShortStroke>();
		}
		// num = penusers.size();
		num = Integer.parseInt(pid.replace("pen", ""));
		// System.out.println("num = "+num+" "+pid);
	}

	public void add(int x, int y) {
		// System.out.println("add (" + penid + ") " + x + " " + y);
		if (graphicsMode == GraphicsMode.AWT) {
			if (lastStroke == null) {
				lastStroke = new Stroke(this);
				stockstrks.add(lastStroke);
			}
			lastStroke.add(x, y);
		} else {
			if (squiggle == null) {
				squiggle = new ShortStroke();
				PNode layer = Note.theapp.getCanvas().getLayer();
				layer.addChild(squiggle);
				squiggle.startDrag_on_draw(x, y);
			} else {
				squiggle.drag_on_draw(x, y);
				PNode layer = Note.theapp.getCanvas().getLayer();
				layer.repaint();
			}
		}
		Note.theapp.repaint();

	}

	public void press(int ph, boolean realPen) {
		System.out.println("press " + ph);
		if (ph == 0) {
			if (graphicsMode == GraphicsMode.AWT) {
				if (lastStroke != null) {
					lastStroke.finish();
					// bundlesend(lastStroke);
					lastStroke = null;
				}
			} else {
				PNode layer = Note.theapp.getCanvas().getLayer();
				if (squiggle.tempPts.size() < 3) {
					layer.removeChild(squiggle);
					squiggle = null;
					return;
				}
				strokes.add(squiggle);
				squiggle.penid = num; // 整数型のPenID
				squiggle.isRealPen = realPen;
				squiggle.endDrag_on_draw(); // 筆記確定後の仕上げをする
				squiggle = null;
			}
		}
	}

	public void draw(Graphics g) {
		g.setColor(Color.getHSBColor((float) (num / 10.0f), 0.8f, 0.8f));
		int count = stockstrks.size();
		for (int i = 0; i < count; i++) {
			Stroke st = stockstrks.get(i);
			st.draw(g);
		}
	}

	public void send(int x, int y, int x2, int y2) {
		Map<String, Object> arg2;
		arg2 = new HashMap<String, Object>();
		arg2.put("penid", penid);
		// arg2.put("phase", drawphase012);
		arg2.put("rgb", getColorStringRGB());
		arg2.put("date", DPenReceiver.sdfdate.format(new Date()));
		arg2.put("time", DPenReceiver.sdftime.format(new Date()));
		arg2.put("epoch", System.currentTimeMillis());
		arg2.put("x1", x);
		arg2.put("y1", y);
		arg2.put("x2", x2);
		arg2.put("y2", y2);
		// parent.ddp.call("/points/insert", new Object[]{arg2});
	}

	public void bundlesend(Stroke st) {
		// Map<String,Object> arg2;
		// arg2 = new HashMap<String, Object>();
		// arg2.put("penid", penid);
		// arg2.put("stroke", st);
		// arg2.put("rgb", getColorStringRGB());
		// parent.ddp.call("/stockstrks
		// insert", new Object[]{arg2});

		// arg2.remove("stroke");
		// parent.ddp.call("pointsclear", new Object[]{arg2});

	}

	public String getColorStringRGB() {
		Color c = Color.getHSBColor((float) (num / 11.0f), 0.8f, 0.8f);
		int r = c.getRed();
		int g = c.getGreen();
		int b = c.getBlue();
		return "rgb(" + r + "," + g + "," + b + ")";
	}
}