00001 package instruction.gui.tab;
00002
00003 import instruction.semanticObjects.Instruction;
00004 import instruction.semanticObjects.ObjectX;
00005 import instruction.semanticObjects.Preposition;
00006 import instruction.semanticObjects.Quantifier;
00007 import instruction.semanticObjects.SemanticObject;
00008 import instruction.semanticObjects.Word;
00009
00010 import java.util.HashMap;
00011 import java.util.Iterator;
00012 import java.util.List;
00013 import java.util.Map;
00014
00015 import processing.core.PApplet;
00016 import processing.core.PFont;
00017
00018 public class DataStructurePanel extends PApplet {
00019
00020 private static final long serialVersionUID = -4061768594124955627L;
00021
00022 private static int FONT_SIZE = 18;
00023
00024 private static int FRAME_WIDTH = 1;
00025 private static int GAP = 50;
00026
00027 PFont font = null;
00028 List<Instruction> instructions = null;
00029 Map<SemanticObject, String> designators = new HashMap<SemanticObject, String>();
00030
00031 int activeInstructionIndex = 0;
00032
00033 int iCounter = 1;
00034 int oCounter = 1;
00035 int pCounter = 1;
00036 int qCounter = 1;
00037
00038 @Override
00039 public void setup() {
00040
00041 size( 2500, 10000, JAVA2D );
00042 background( 255 );
00043 noLoop();
00044 font = createFont( "Arial", FONT_SIZE, true );
00045 smooth();
00046
00047 }
00048
00049 @Override
00050 public void draw() {
00051
00052 fill( 0 );
00053 iCounter = oCounter = qCounter = pCounter = 1;
00054 textFont( font );
00055 background( 255 );
00056 if ( instructions == null ) {
00057 return;
00058 }
00059 generateDesignatorMap( instructions );
00060
00061 float vSum = 0;
00062
00063
00064
00065
00066 _draw( instructions.get( activeInstructionIndex ), GAP, vSum + GAP );
00067
00068 }
00069
00070 public float _draw( SemanticObject so, float hOffset, float vOffset ) {
00071
00072 float vSum = 0;
00073
00074 if ( so instanceof Instruction ) {
00075 Instruction inst = (Instruction) so;
00076
00077 float[] size = drawSemanticObject( getInstructionString( inst ), hOffset, vOffset );
00078
00079 for ( Iterator<ObjectX> i = inst.getObjects().iterator(); i.hasNext(); ) {
00080 float sum = vSum;
00081 vSum += _draw( i.next(), hOffset + size[0] + GAP, vOffset + vSum ) + GAP;
00082 stroke( 1 );
00083 fill( 232, 238, 247 );
00084 line( hOffset + size[0], vOffset + size[1] / 2 + 5, hOffset + size[0] + GAP, vOffset + sum + 50 );
00085 ellipse( hOffset + size[0] - 5, vOffset + size[1] / 2, 10, 10 );
00086 noStroke();
00087 }
00088
00089 for ( Iterator<Preposition> i = inst.getPrepositions().iterator(); i.hasNext(); ) {
00090 float sum = vSum;
00091 vSum += _draw( i.next(), hOffset + size[0] + GAP, vOffset + vSum ) + GAP;
00092 stroke( 1 );
00093 fill( 232, 238, 247 );
00094 line( hOffset + size[0], vOffset + size[1] / 2 + 25, hOffset + size[0] + GAP, vOffset + sum + 50 );
00095 ellipse( hOffset + size[0] - 5, vOffset + size[1] / 2 + 20, 10, 10 );
00096 noStroke();
00097 }
00098
00099 if ( inst.getTimeConstraint() != null ) {
00100 float sum = vSum;
00101 vSum += _draw( inst.getTimeConstraint(), hOffset + size[0] + GAP, vOffset + vSum ) + GAP;
00102 stroke( 1 );
00103 fill( 232, 238, 247 );
00104 line( hOffset + size[0], vOffset + size[1] / 2 + 45, hOffset + size[0] + GAP, vOffset + sum + 50 );
00105 ellipse( hOffset + size[0] - 5, vOffset + size[1] / 2 + 40, 10, 10 );
00106 noStroke();
00107 }
00108
00109 if ( inst.getTimeConstraint() == null && inst.getObjects().isEmpty()
00110 && inst.getPrepositions().isEmpty() )
00111 vSum += size[1];
00112
00113 }
00114
00115 else if ( so instanceof ObjectX ) {
00116 ObjectX o = (ObjectX) so;
00117
00118 float[] size = drawSemanticObject( getObjectString( o ), hOffset, vOffset );
00119
00120 for ( Iterator<Preposition> i = o.getPrepositions().iterator(); i.hasNext(); ) {
00121 float sum = vSum;
00122 vSum += _draw( i.next(), hOffset + size[0] + GAP, vOffset + vSum ) + GAP;
00123 stroke( 1 );
00124 fill( 232, 238, 247 );
00125 line( hOffset + size[0], vOffset + size[1] / 2 + 15, hOffset + size[0] + GAP, vOffset + sum + 50 );
00126 ellipse( hOffset + size[0] - 5, vOffset + size[1] / 2 + 10, 10, 10 );
00127 noStroke();
00128 }
00129
00130 if ( ! o.getQuantifier().getAlternatives().isEmpty()
00131 || ! o.getQuantifier().getMeasure().getLabel().isEmpty() ) {
00132 float sum = vSum;
00133 vSum += _draw( o.getQuantifier(), hOffset + size[0] + GAP, vOffset + vSum );
00134 stroke( 1 );
00135 fill( 232, 238, 247 );
00136 line( hOffset + size[0], vOffset + size[1] / 2 + 35, hOffset + size[0] + GAP, vOffset + sum + 40 );
00137 ellipse( hOffset + size[0] - 5, vOffset + size[1] / 2 + 30, 10, 10 );
00138 noStroke();
00139
00140 }
00141 else
00142 vSum += size[1];
00143 }
00144
00145 else if ( so instanceof Preposition ) {
00146 Preposition p = (Preposition) so;
00147
00148 float[] size = drawSemanticObject( getPrepositionString( p ), hOffset, vOffset );
00149
00150 for ( Iterator<ObjectX> i = p.getObjects().iterator(); i.hasNext(); ) {
00151 float sum = vSum;
00152 vSum += _draw( i.next(), hOffset + size[0] + GAP, vOffset + vSum );
00153 stroke( 1 );
00154 fill( 232, 238, 247 );
00155 line( hOffset + size[0], vOffset + size[1] / 2 + 20, hOffset + size[0] + GAP, vOffset + sum + 50 );
00156 ellipse( hOffset + size[0] - 5, vOffset + size[1] / 2 + 15, 10, 10 );
00157 noStroke();
00158 }
00159 if ( p.getObjects().isEmpty() )
00160 vSum += size[1];
00161 }
00162
00163 else if ( so instanceof Quantifier ) {
00164 float[] size = drawSemanticObject( getQuantifierString( (Quantifier) so ), hOffset, vOffset );
00165 vSum += size[1];
00166 }
00167
00168 return vSum;
00169 }
00170
00171 public void roundRect( float x, float y, float width, float height, float radius ) {
00172
00173
00174 stroke( 1 );
00175 fill( 0 );
00176 rect( x + radius, y, width - 2 * radius, height );
00177 rect( x, y + radius, width, height - 2 * radius );
00178 ellipseMode( CORNER );
00179 ellipse( x, y, radius * 2, radius * 2 );
00180 ellipse( x + width - 2 * radius, y, 2 * radius, 2 * radius );
00181 ellipse( x, y + height - 2 * radius, 2 * radius, 2 * radius );
00182 ellipse( x + width - 2 * radius, y + height - 2 * radius, 2 * radius, 2 * radius );
00183
00184
00185 fill( 232, 238, 247 );
00186 noStroke();
00187 rect( x + radius + FRAME_WIDTH, y + FRAME_WIDTH, width - 2 * radius - FRAME_WIDTH, height - FRAME_WIDTH );
00188 rect( x + FRAME_WIDTH, y + radius + FRAME_WIDTH, width - FRAME_WIDTH, height - 2 * radius - FRAME_WIDTH );
00189
00190 ellipse( x + FRAME_WIDTH, y + FRAME_WIDTH, radius * 2, radius * 2 );
00191 ellipse( x + width - 2 * radius + FRAME_WIDTH, y + FRAME_WIDTH, 2 * radius - FRAME_WIDTH, 2 * radius
00192 - FRAME_WIDTH );
00193 ellipse( x + FRAME_WIDTH, y + height - 2 * radius + FRAME_WIDTH, 2 * radius - FRAME_WIDTH, 2 * radius
00194 - FRAME_WIDTH );
00195 ellipse( x + width - 2 * radius + FRAME_WIDTH, y + height - 2 * radius + FRAME_WIDTH, 2 * radius
00196 - FRAME_WIDTH, 2 * radius - FRAME_WIDTH );
00197
00198 }
00199
00200 public float[] drawSemanticObject( String str, float hOffset, float vOffset ) {
00201
00202 float width = textWidth( str );
00203 int lines = 1;
00204 int idx = 0;
00205 while ( ( idx = str.indexOf( "\n", idx ) ) != - 1 ) {
00206 lines++;
00207 idx++;
00208 }
00209 float height = lines * ( textDescent() + FONT_SIZE + 4 );
00210
00211
00212
00213
00214 roundRect( hOffset, vOffset, width + 20, height + 20, 5 );
00215 fill( 0 );
00216 text( str, 10 + hOffset, vOffset + 10, width, height );
00217 float[] ret = new float[2];
00218 ret[0] = width + 20;
00219 ret[1] = height;
00220 return ret;
00221 }
00222
00223 public String getInstructionString( Instruction i ) {
00224
00225 StringBuffer str = new StringBuffer();
00226 str.append( "Instruction " + designators.get( i ) + "\n" );
00227 str.append( "Action: \"" + i.getAction().getAction().getLabel() + "\" ("
00228 + i.getAction().getAction().getCycConcepts().get( 0 ) + ")\n" );
00229 str.append( "Objects: { " );
00230
00231 for ( Iterator<ObjectX> j = i.getObjects().iterator(); j.hasNext(); ) {
00232 str.append( designators.get( j.next() ) + ( j.hasNext() ? "," : "" ) );
00233 }
00234 str.append( " }\n" );
00235 str.append( "Postcondition: { " );
00236 for ( Iterator<Preposition> j = i.getPrepositions().iterator(); j.hasNext(); ) {
00237 str.append( designators.get( j.next() ) + ( j.hasNext() ? "," : "" ) );
00238 }
00239 str.append( " }\n" );
00240 str.append( "Duration: " + designators.get( i.getTimeConstraint() ) );
00241
00242 return str.toString();
00243 }
00244
00245 public String getObjectString( ObjectX o ) {
00246
00247 StringBuffer str = new StringBuffer();
00248 str.append( "Object " + designators.get( o ) + "\n" );
00249 str.append( "Name: \"" + o.getName().get( 0 ).getLabel() + "\" ("
00250 + o.getName().get( 0 ).getCycConcepts().get( 0 ) + ")\n" );
00251 str.append( "Prepositions: { " );
00252 for ( Iterator<Preposition> j = o.getPrepositions().iterator(); j.hasNext(); ) {
00253 str.append( designators.get( j.next() ) + ( j.hasNext() ? "," : "" ) );
00254 }
00255 str.append( " }\n" );
00256 String q = designators.get( o.getQuantifier() );
00257 str.append( "Quantifier: " + ((o.getQuantifier().getAlternatives().isEmpty() && o.getQuantifier().getMeasure().getLabel().isEmpty()) ? "null" : q));
00258
00259 return str.toString();
00260 }
00261
00262 public String getPrepositionString( Preposition p ) {
00263
00264 StringBuffer str = new StringBuffer();
00265 str.append( "Preposition " + designators.get( p ) + "\n" );
00266 str.append( "Prep: \"" + p.getPrepositions().get( 0 ).getLabel() + "\"\n" );
00267 str.append( "Objects: { " );
00268 for ( Iterator<ObjectX> j = p.getObjects().iterator(); j.hasNext(); ) {
00269 str.append( designators.get( j.next() ) + ( j.hasNext() ? "," : "" ) );
00270 }
00271 str.append( " }\n" );
00272
00273 return str.toString();
00274 }
00275
00276 public String getQuantifierString( Quantifier q ) {
00277
00278 StringBuffer str = new StringBuffer();
00279 str.append( "Quantifier " + designators.get( q ) + "\n" );
00280 str.append( "Amount: {" );
00281 for ( Iterator<Word> j = q.getAlternatives().iterator(); j.hasNext(); ) {
00282 str.append( j.next().getLabel() + ( j.hasNext() ? ", " : "" ) );
00283 }
00284 str.append( "}\n" );
00285 str.append( "Measure: " + q.getMeasure().getLabel() );
00286 if ( ! q.getMeasure().getLabel().isEmpty() )
00287 str.append( " (" + q.getMeasure().getCycConcepts().get( 0 ) + ")" );
00288
00289 return str.toString();
00290 }
00291
00292 public void setInstructions( List<Instruction> instructions ) {
00293
00294 this.instructions = instructions;
00295 }
00296
00297 @SuppressWarnings("unchecked")
00298 public void generateDesignatorMap( List so ) {
00299
00300 for ( Iterator<SemanticObject> i = so.iterator(); i.hasNext(); ) {
00301 generateDesignatorMap( i.next() );
00302 }
00303 }
00304
00305 public void generateDesignatorMap( SemanticObject so ) {
00306
00307 if ( so instanceof Instruction ) {
00308 Instruction i = (Instruction) so;
00309 designators.put( i, "i" + iCounter++ );
00310 generateDesignatorMap( i.getObjects() );
00311 generateDesignatorMap( i.getPrepositions() );
00312 generateDesignatorMap( i.getTimeConstraint() );
00313 }
00314 else if ( so instanceof ObjectX ) {
00315 ObjectX o = (ObjectX) so;
00316 designators.put( o, "o" + oCounter++ );
00317 generateDesignatorMap( o.getPrepositions() );
00318 generateDesignatorMap( o.getQuantifier() );
00319 }
00320 else if ( so instanceof Quantifier ) {
00321 designators.put( so, "q" + qCounter++ );
00322 }
00323 else if ( so instanceof Preposition ) {
00324 Preposition p = (Preposition) so;
00325 designators.put( p, "p" + pCounter++ );
00326 generateDesignatorMap( p.getObjects() );
00327 }
00328 }
00329
00330 public int getActiveInstruction() {
00331
00332 return activeInstructionIndex;
00333 }
00334
00335 public void setActiveInstruction( int idx ) {
00336
00337 activeInstructionIndex = idx;
00338 }
00339
00340 public int getInstructionCount() {
00341
00342 if ( instructions == null )
00343 return 0;
00344 else
00345 return instructions.size();
00346 }
00347 }