package dtclient;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.lang.reflect.Method;
import java.net.Socket;
import java.net.SocketException;
import java.util.Vector;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.sun.org.apache.xerces.internal.parsers.DOMParser;
import dtclient.DTMarker;
import processing.core.PApplet;
/**
* @author Enrico Costanza <e.costanza@ieee.org>
* This file is part of libdtouch.
*
* libdtouch is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* libdtouch is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libdtouch. If not, see <http://www.gnu.org/licenses/>.
*/
public class InnerDTClient implements Runnable{
Socket _socket;
boolean _quitFlag;
String _host ="127.0.0.1";
int _port = 1234;
Method _onData;
PApplet _parent;
DOMParser parser = new DOMParser();
public InnerDTClient( PApplet in_parent ) {
_parent = in_parent;
try {
_onData = _parent.getClass().getMethod( "dtUpdate", new Class[] { Vector.class } );
} catch (Exception e) {
// do nothing
}
}
public Vector parse( String xml ){
Vector result = new Vector();
try {
parser.parse( new InputSource(new StringReader(xml)) );
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Document doc = parser.getDocument();
Node frameNode = doc.getElementsByTagName("FRAME").item(0);
if( frameNode==null ){
return result;
}
//int nMarkers = Integer.parseInt( frameNode.getAttributes().getNamedItem("n").getTextContent() );
int framew = Integer.parseInt(frameNode.getAttributes().getNamedItem("w").getTextContent());
int frameh = Integer.parseInt(frameNode.getAttributes().getNamedItem("h").getTextContent());
NodeList markerNodes = doc.getElementsByTagName("MARKER");
for(int i=0;i<markerNodes.getLength();i++){
NamedNodeMap attribs = markerNodes.item(i).getAttributes();
// id, x, y, angle, w, h
attribs.getNamedItem("");
int id = Integer.parseInt(attribs.getNamedItem("id").getTextContent());
int x = Integer.parseInt(attribs.getNamedItem("x").getTextContent());
int y = Integer.parseInt(attribs.getNamedItem("y").getTextContent());
int angle = Integer.parseInt(attribs.getNamedItem("angle").getTextContent());
int size = Integer.parseInt(attribs.getNamedItem("size").getTextContent());
int w = Integer.parseInt(attribs.getNamedItem("w").getTextContent());
int h = Integer.parseInt(attribs.getNamedItem("h").getTextContent());
DTMarker data = new DTMarker(id,x,y,angle,size,w,h,framew,frameh);
result.add(data);
}
return result;
}
private void connect(){
boolean connected = false;
// while not connected
while( !connected ){
// try connecting
try {
_socket = new Socket(_host,_port);
} catch (IOException e) {
// and sleep 10 seconds if it fails
try {
Thread.sleep( 10000 );
} catch (InterruptedException ie) {
// do nothing
}
continue;
}
connected = true;
}
}
public void run() {
// while quit not requested
while( !_quitFlag ){
this.connect();
// we are connected
// set up all the necessary stuff
// to read from the socket
InputStreamReader in = null;
try {
in = new InputStreamReader( _socket.getInputStream() );
} catch (IOException e) {
e.printStackTrace();
}
// this where we accumulate the receive buffer
String message = new String();
char buff[] = new char[1];
// while connected
while( _socket.isConnected() ){
// read and decode data
try {
in.read(buff);
if( buff[0] == 0 ){
// got the message, time to parse
Vector data = parse(message);
//for(int i=0;i<data.size();i++){ System.out.println( ((DTMarker) data.get(i)).toString() ); }
// do something actually useful with the data..
OnData(data);
// reset buffer
message = "";
}else{
// keep accumulating data
message += buff[0];
}
} catch (SocketException se) {
// looks like the server disconnected
//System.out.println("looks like the server disconnected");
break;
} catch (IOException ioe) {
ioe.printStackTrace();
break;
}
}
}
// clean up before exiting
if( _socket != null ){
try {
_socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void OnData( Vector markers ){
if( markers != null ){
if( _onData != null ){
try { _onData.invoke(_parent, new Object[] { markers } ); }
catch (Exception e) {
_onData = null;
e.printStackTrace();
System.out.println( "invoke threw " + e.getMessage() );
}
}
/*
if( _printFlag ){
System.out.println( markers.size() + " marker(s)" );
for(int i=0;i<markers.size();i++){
System.out.println( " "+((DTMarker)markers.elementAt(i)).toString() );
}
}*/
}
}
public void quit(){
_quitFlag = true;
}
}