package tcra.exercises.q2_mystery_private;

import java.util.*;
import tcra.math.*;

public class Q2MysteryExercise_PostMystery4Assertion implements
      Assertion
{
   public Q2MysteryExercise_PostMystery4Assertion() {}

   @SuppressWarnings("unchecked")
   public boolean check(List<MathType> t)
   {
      MathString<MathType> lb_self = (MathString<MathType>)t.get(0);
      MathInteger          lb_a    = (MathInteger)t.get(1);
      MathInteger          lb_b    = (MathInteger)t.get(2);
      MathString<MathType> self    = (MathString<MathType>)t.get(3);
      MathInteger          a       = (MathInteger)t.get(4);
      MathInteger          b       = (MathInteger)t.get(5);
      
      MathString<MathType> A, B, C, temp;
      MathInteger          D, E;
      
      A = lb_self.split(lb_a.getValue()-1).get(0);
      temp = lb_self.split(lb_a.getValue()-1).get(1);
      D = (MathInteger)temp.elementAt(0);
      temp = temp.split(0).get(1);
      B = temp.split(lb_b.getValue() - lb_a.getValue() - 2).get(0);
      temp = temp.split(lb_b.getValue() - lb_a.getValue() - 2).get(1);
      E = (MathInteger)temp.elementAt(0);
      C = temp.split(0).get(1);
      
      temp = B.prepend(D);
      MathString<MathType> temp2 = C.prepend(E);
            
      if(!lb_self.equals(A.concat(temp.concat(temp2)))) return false;
      if(A.length() != lb_a.getValue()) return false;
      if(A.concat(temp).length() != lb_b.getValue()) return false;
      
      temp = B.prepend(E);
      temp2 = C.prepend(D);
      
      if(!self.equals(A.concat(temp.concat(temp2)))) return false;
      
      return true;
   } // end check(List)
   
   public String toString()
   {
      return("there exists A, B, C: String of Object; D, E: Object such that<br>"+
             "#self = A * &lt;D&gt; * B * &lt;E&gt; * C and<br>"+
             "|A| = a and<br>"+
             "|A * &lt;D&gt; * B| = b and<br>"+
             "self = A * &lt;E&gt; * B * &lt;D&gt; * C;");
   } // end toString()

   @SuppressWarnings("unchecked")
   public String toInstanceString(List<MathType> t)
   {
      MathString<MathType> lb_self = (MathString<MathType>)t.get(0);
      MathInteger          lb_a    = (MathInteger)t.get(1);
      MathInteger          lb_b    = (MathInteger)t.get(2);
      MathString<MathType> self    = (MathString<MathType>)t.get(3);
      MathInteger          a       = (MathInteger)t.get(4);
      MathInteger          b       = (MathInteger)t.get(5);
	      
      MathString<MathType> A, B, C, temp;
      MathInteger          D, E;
	  
      A = lb_self.split(lb_a.getValue()-1).get(0);
      temp = lb_self.split(lb_a.getValue()-1).get(1);
      D = (MathInteger)temp.elementAt(0);
      temp = temp.split(0).get(1);
      B = temp.split(lb_b.getValue() - lb_a.getValue() - 2).get(0);
      temp = temp.split(lb_b.getValue() - lb_a.getValue() - 2).get(1);
      E = (MathInteger)temp.elementAt(0);
      C = temp.split(0).get(1);
      
      return("there exists A, B, C: String of Object; D, E: Object such that<br>"+
              lb_self.toHTMLString()+" = "+A.toHTMLString()+" * &lt;"+D.toHTMLString()+
              "&gt; * "+B.toHTMLString()+" * &lt;"+E.toHTMLString()+"&gt; * "+
              C.toHTMLString()+" and<br>"+
              "|"+A.toHTMLString()+"| = "+lb_a.toHTMLString()+" and<br>"+
              "|"+A.toHTMLString()+" * &lt;"+D.toHTMLString()+"&gt; * "+B.toHTMLString()+"| = "+lb_b.toHTMLString()+" and<br>"+
              self.toHTMLString()+" = "+A.toHTMLString()+" * &lt;"+
              E.toHTMLString()+"&gt; * "+B.toHTMLString()+" * &lt;"+
              D.toHTMLString()+"&gt; * "+C.toHTMLString()+";");
   } // end toInstanceString(List)
} // end class
