package jp.ac.kyutech.mns.ist;
import java.awt.Color;
import java.awt.Font;
import java.awt.geom.Dimension2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import org.josql.Query;
import org.josql.QueryExecutionException;
import org.josql.QueryParseException;
import org.josql.QueryResults;
import jp.ac.kyutech.mns.ist.filter.AvgVarCalc2;
import jp.ac.kyutech.mns.ist.util.BUtil;
import pothos_tegaki.PothosLibRecognizer;
import pothos_tegaki.TegakiCallBack;
import pothos_tegaki.TegakiRecogTask;
import edu.umd.cs.piccolo.PCamera;
import edu.umd.cs.piccolo.PCanvas;
import edu.umd.cs.piccolo.PNode;
import edu.umd.cs.piccolo.event.PBasicInputEventHandler;
import edu.umd.cs.piccolo.event.PInputEvent;
import edu.umd.cs.piccolo.nodes.PPath;
import edu.umd.cs.piccolo.nodes.PText;
import edu.umd.cs.piccolo.util.PBounds;
public class FocusRectangle extends PPath implements TegakiCallBack, LayoutContent {
private static final long serialVersionUID = 89458177638758913L;
public static Font defaultFont = new Font("SansSerif", Font.PLAIN, 30);
public static Color defaultLabelRoundColor = Color.LIGHT_GRAY;
public static float rlw = 20f;
public transient PCamera cam;
public PPath backGround;
transient PPath handle;
// transient PPath highlight;
PText pt_penid;
Sheet sheet;
PCanvas canvas;
public FocusSrc focussrc;
public FRPalette palette;
public Rectangle2D mysize; //レイアウト用のサイズ.Palette含まず
public Event_onFR event_onfr;
public static PothosLibRecognizer recognizer = null;
static {
try{
// recognizer = new PothosLibRecognizer(); //TODO:
}catch(UnsatisfiedLinkError ue){
recognizer = null;
}
}
public Note getNote(){
return sheet.getNote();
}
public Rectangle2D mysize(){
return mysize;
}
public boolean hasContent(){
return true;
}
public FocusRectangle(Dimension2D size, Sheet _sheet, Rectangle2D viewRegion, PCanvas _focuscanvas){
double worh = (size.getWidth() > size.getHeight() )? size.getWidth() : size.getHeight();
if (_sheet.getNote().isLandscapeMode){
setPathTo(
new RoundRectangle2D.Double(0,0,size.getHeight()+(size.getHeight()/rlw),
size.getWidth()+(size.getHeight()/rlw),size.getWidth()/(worh/rlw),size.getWidth()/(worh/rlw)));
} else {
setPathTo(new RoundRectangle2D.Double(0,0,size.getWidth()+(size.getWidth()/rlw),
size.getHeight()+(size.getWidth()/rlw),size.getHeight()/(worh/rlw),size.getHeight()/(worh/rlw)));
}
sheet = _sheet;
canvas = _focuscanvas;
this.setTransparency(1.0f);
this.setStrokePaint(null);
//シート上でのマウス操作
event_onfr = new Event_onFR(this);
addInputEventListener(event_onfr);
backGround = new PPath(this.getPathReference());
backGround.setTransparency(1.0f);
backGround.setPaint(defaultLabelRoundColor);
backGround.setStroke(Note.getCachedBasicStroke((float)(worh/(rlw*(1.0f+(rlw/worh))))));
backGround.setStrokePaint(defaultLabelRoundColor);
addChild(backGround);
resetCam();
cam.setViewBounds(viewRegion);
cam.repaint();
//レイアウト用のサイズ
mysize = getFullBounds();
palette = new FRPalette(this);
palette.setVisible(false);
if (cam.getWidth() < palette.getWidth()){
palette.setScale(cam.getWidth()/palette.getWidth());
pt_penid.setScale(cam.getWidth()/palette.getWidth());
pt_penid.setOffset(getWidth()-pt_penid.getWidth()*pt_penid.getScale(),
getHeight()-pt_penid.getHeight()*pt_penid.getScale());
// if (pt_penid.getText().equals("23")){ //for debug
// new DebugPanel(pt_penid,"PenID");
// new DebugPanel(palette,"Palette");
// new DebugPanel(this,"FR");
// }
palette.fitToFR();
}
}
public void focus(){
focus(1000, true);
}
public void focus(int msec, boolean updateFRef){
//フォーカス
Rectangle2D globalb = getGlobalBounds();
canvas.getCamera().animateViewToCenterBounds(globalb, true, msec);
sheet.isshowImage(true);
if (updateFRef) FocusFrame.updateFocusReference(sheet.getNote().penid);
}
public void focusReference(){
Rectangle2D globalb = getGlobalBounds();
canvas.getCamera().setViewBounds(globalb);
sheet.isshowImage(true);
}
public void setLabelRoundColor(Color c){
if (backGround != null) backGround.setStrokePaint(c);
}
public void resetCam(){
if (cam == null){
cam = new PCamera();
cam.setPickable(true);
addChild(cam);
// cam.setOffset(3,3);
cam.setBounds(BUtil.plusBounds(this.getBounds(), -10, -10));
cam.addAttribute("moveTarget", this);
cam.addLayer(sheet.canvas.getLayer());
}
// if (highlight == null){
// highlight = new PPath(this.getPathReference());
// highlight.setVisible(false);
// highlight.setPaint(Color.yellow);
// highlight.setStrokePaint(Color.red);
// highlight.setStroke(Note.getCachedBasicStroke(10f));
// highlight.setPickable(false);
// addChild(highlight);
// highlight.moveToFront();
// }
if (handle == null){
handle = new PPath(this.getPathReference());
handle.addAttribute("moveTarget", this);
handle.setTransparency(0.0f);
handle.setPaint(Color.pink);
handle.setStrokePaint(Color.red);
handle.setStroke(Note.getCachedBasicStroke(10f));
handle.setPickable(true);
addChild(handle);
handle.moveToFront();
handle.addInputEventListener(new PBasicInputEventHandler(){
public void mouseEntered(PInputEvent e){
focussrc.isHover(true);
palette.setVisible(true);
FocusFrame.updateFocusReference(sheet.getNote().penid);
}
public void mouseExited(PInputEvent e){
focussrc.isHover(false);
palette.setVisible(false);
}
});
}
if (handle != null) {
handle.moveToFront();
// handle.addAttribute("drawTarget", student.sheetHash.get(tagid/100).ink);
// handle.addAttribute("drawOffset", cam.getViewBounds().getOrigin());
handle.addInputEventListener(new PBasicInputEventHandler(){
public void mouseEntered(PInputEvent event){
}
public void mouseExited(PInputEvent event){
}
});
}
if (pt_penid == null){
pt_penid = new PText(String.valueOf(sheet.getNote().penid));
pt_penid.setScale(2f);
pt_penid.setTransparency(0.6f);
pt_penid.offset(getWidth()-pt_penid.getWidth()*pt_penid.getScale()-10, getHeight()-pt_penid.getHeight()*pt_penid.getScale()-10);
addChild(pt_penid);
}
}
public void updateSize(int size){
setPathTo(new RoundRectangle2D.Double(-size/2,-size/2,size*2,size,size/6,size/6));
cam.setBounds(getBounds());
cam.setViewBounds(sheet.getGlobalBounds());
// cam.setViewBounds(new PBounds(0,0,700,990));
cam.repaint();
}
/**
* フィールドに対して,任意のメッセージを投げる
* 例:
* @param target
* @param field
* @param method
* @param argtypes
* @param args
*/
public void callFieldMethod(String target, String field, String method, Class<?>[] argtypes, Object... args) {
try {
Field f = Sheet.class.getField(field);
Object pn = f.get(this);
Method m = pn.getClass().getMethod(method, argtypes);
m.invoke(pn, args);
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
/**
* フィールドを引数としたメソッドを呼ぶ.ただし,フィールドはすべてPNodeで,引数は1つ
* 例:stu.callMethodWithFieldArg("sheet","copyrect_page","addChild");
* @param target
* @param fieldarg
* @param method
*/
public void callMethodWithFieldArg(String target, String fieldarg, String method) {
try {
Field f = Sheet.class.getField(fieldarg);
Object farg = f.get(this);
Method m = getClass().getMethod(method, farg.getClass());
m.invoke(this, farg);
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
/**
* フィールドを引数としたメソッドを呼ぶ.ただし,フィールドはすべてPNodeで,引数は複数
* 例:stu.callMethodWithFieldArg("sheet","copyrect_page","addChild");
* @param target
* @param object
* @param method
*/
public void callMethodWithFieldMultipleArgs(String target, String[] objects, Class<?>[] argtypes, String method) {
try {
ArrayList<Object> pns = new ArrayList<Object>();
for(String object: objects){
Field f = FocusRectangle.class.getField(object);
pns.add(f.get(this));
}
Method m = getClass().getMethod(method, argtypes);
m.invoke(this, pns.toArray());
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
public void setFocusSrc(FocusSrc _fs) {
focussrc = _fs;
}
public void updateCameraView(){
// if (focussrc == null) return;
PBounds pb = focussrc.getGlobalBounds();
cam.animateViewToCenterBounds(pb, false, 1000);
}
//筆記量の調査
public int drawingAmount() {
int num = 0;
@SuppressWarnings("unchecked")
Collection<PNode> c = (Collection<PNode>)sheet.getAllNodes();
Rectangle2D rect = focussrc.getBounds();
for(PNode pn: c){
if (rect.contains(pn.getBounds())) num++;
}
return num;
}
//文字認識
public void recognize() {
ArrayList<ShortStroke> ssvec = new ArrayList<ShortStroke>();
@SuppressWarnings("unchecked")
Collection<PNode> c = (Collection<PNode>)sheet.getAllNodes();
Rectangle2D rect = focussrc.getBounds();
for(PNode pn: c){
if (pn instanceof ShortStroke){
if (rect.contains(pn.getBounds())) {
ssvec.add((ShortStroke)pn);
}
}
}
TegakiRecogTask trt = new TegakiRecogTask(this);
trt.setSSVec(ssvec);
System.out.println(recognizer.recognize(trt));
}
@Override
public void callback(TegakiRecogTask s) {
System.out.println(s.result);
}
@Override
public double teineiLevel() {
ArrayList<ShortStroke> ssvec = new ArrayList<ShortStroke>();
@SuppressWarnings("unchecked")
Collection<PNode> c = (Collection<PNode>)sheet.getAllNodes();
Rectangle2D rect = focussrc.getBounds();
for(PNode pn: c){
if (pn instanceof ShortStroke){
if (rect.contains(pn.getBounds())) {
ShortStroke ss = (ShortStroke)pn;
ss.calcMetrics();
//ramer>-1 and pts<=30 and dist<=77
if (ss.ramer<0) continue;
if (ss.pts>30) continue;
if (ss.dist>77) continue;
ssvec.add(ss);
}
}
}
double m1 = varPpdR1(ssvec);
double m2 = avgRamer(ssvec);
double m3 = avgPpd(ssvec);
// TODO Auto-generated method stub
double ret = m1+m2+m3;
System.out.println(sheet.getNote().penid+" "+ret);
return ret;
}
public double varPpdR1(ArrayList<ShortStroke> ass){
Query q1 = new Query();
try {
q1.parse("select * from jp.ac.kyutech.mns.ist.ShortStroke where ramer=1");
} catch (QueryParseException e) { e.printStackTrace();}
QueryResults qr1=null;
try {
qr1 = q1.execute(ass);
} catch (QueryExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
AvgVarCalc2<ShortStroke> calc1 = new AvgVarCalc2<ShortStroke>(new String[]{"pts","ppd","var_ramer","dist","ramer"}, (ArrayList<ShortStroke>)qr1.getResults());
if (calc1.getcnt("ppd")<4) return 2;
double varppd1 = calc1.getvar("ppd");
return varppd1;
}
public double avgRamer(ArrayList<ShortStroke> ass){
AvgVarCalc2<ShortStroke> calc1 = new AvgVarCalc2<ShortStroke>(new String[]{"pts","ppd","var_ramer","dist","ramer"}, ass);
if (calc1.getcnt("ramer")<4) return 2;
return calc1.getavg("ramer");
}
public double avgPpd(ArrayList<ShortStroke> ass){
AvgVarCalc2<ShortStroke> calc1 = new AvgVarCalc2<ShortStroke>(new String[]{"pts","ppd","var_ramer","dist","ramer"}, ass);
if (calc1.getcnt("ppd")<4) return 2;
return calc1.getavg("ppd");
}
}