package tcra.exercises.resolve_random_access_capability_private;

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

public class ResolveRandomAccessCapability_InsertContract extends
       MethodContract
{
    protected MathString<MathType> lb_self;
    protected MathString<MathType> self;
    protected MathInteger          lb_insert;
    protected MathInteger          insert;
    protected MathInteger          lb_index;
    protected MathInteger          index;
   
   public ResolveRandomAccessCapability_InsertContract()
   {
      super("Insert");
      precondition  =
               new ResolveRandomAccessCapability_PreInsertAssertion();
      postcondition =
              new ResolveRandomAccessCapability_PostInsertAssertion();
      args = new Vector<MethodArgument>();
      args.add(new MethodArgument("i", new IntegerType()));
      args.add(new MethodArgument("k", new IntType()));
      returnType = new VoidType();
      
      lb_self = self = null;
      lb_insert = insert = lb_index = index = null;
   } // end ctor
   
   @Override
   public boolean check(String[] l) throws MathFormatException
   {
      MathIntegerParser mip = new MathIntegerParser();
      MathStringParser  msp = new MathStringParser(mip);
      
      lb_self   = msp.parse(new StringBuilder(l[0]));
      lb_insert = mip.parse(new StringBuilder(l[1]));
      lb_index  = mip.parse(new StringBuilder(l[2]));
      self      = msp.parse(new StringBuilder(l[3]));
      insert    = mip.parse(new StringBuilder(l[4]));
      index     = mip.parse(new StringBuilder(l[5]));
      
      if(lb_self   == null || self   == null ||
         lb_insert == null || insert == null ||
         lb_index  == null || index  == null)
         throw new MathFormatException(
                   "One or more unparsable arguments.");
      
      Vector<MathType> state = new Vector<MathType>();
      state.add(lb_self);
      state.add(lb_insert);
      state.add(lb_index);
      state.add(self);
      state.add(insert);
      state.add(index);
      
      return (precondition.check(state) &&
              postcondition.check(state));
   } // end check(String[])

   public String toString()
   {
      return ("<html>Operation Insert(alters I:Integer; restores k:"+
              " Integer; updates S: StackI);<br>"+
              "requires:<br>" +precondition+
              "<br>ensures:<br>" +postcondition);
   } // end toString
   
   public String toInstanceString()
   {
      Vector<MathType> state = new Vector<MathType>();
      state.add(lb_self);
      state.add(lb_insert);
      state.add(lb_index);
      state.add(self);
      state.add(insert);
      state.add(index);
      
      return("<html>Operation Insert(alters I:Integer; restores k:"+
             " Integer; updates S: StackI);<br>"+
             "requires:<br>" +precondition.toInstanceString(state)+
             "<br>ensures:<br>" +
             postcondition.toInstanceString(state));
   } // end toInstanceString
} // end class
