package x2x.translator.xcodeml;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class CLAWloop {
  protected Element _pragmaElement = null;
  protected Element _loopElement = null;

  protected Element _rangeElement = null;
  protected Element _rangeVarElement = null;

  protected String _iterationVar;
  protected String _lowerBoundValue;
  protected String _upperBoundValue;
  protected String _stepValue;



  public CLAWloop(Element pragma, Element loop){
    _pragmaElement = pragma;
    _loopElement = loop;

    NodeList vars = _loopElement.getElementsByTagName("Var");
    Element var = (Element) vars.item(0);
    _rangeVarElement = var;
    _iterationVar = var.getTextContent();
    NodeList ranges = _loopElement.getElementsByTagName("indexRange");
    Element range = (Element) ranges.item(0);
    _rangeElement = range;

    _lowerBoundValue = getRangeValue("lowerBound");
    _upperBoundValue = getRangeValue("upperBound");
    _stepValue = getRangeValue("step");
  }

  private String getRangeValue(String tag){
    NodeList rangeElements = _loopElement.getElementsByTagName(tag);
    Element rangeElement = (Element) rangeElements.item(0);
    NodeList constants = rangeElement.getElementsByTagName("FintConstant");
    Element constant = (Element) constants.item(0);
    return constant.getTextContent();
  }

  private void setRangeValue(String tag, String newValue){
    NodeList rangeElements = _loopElement.getElementsByTagName(tag);
    Element rangeElement = (Element) rangeElements.item(0);
    NodeList constants = rangeElement.getElementsByTagName("FintConstant");
    Element constant = (Element) constants.item(0);
    constant.setTextContent(newValue);
  }

  public void setNewRange(String iterationVariable, String lowerBound,
    String upperBound, String step){
      _rangeVarElement.setTextContent(iterationVariable);
      setRangeValue("lowerBound", lowerBound);
      setRangeValue("upperBound", upperBound);
      setRangeValue("step", step);
  }

  public void setNewRange(Element var, Element range){
    Element body = getBodyElement();
    _loopElement.insertBefore(var, body);
    _loopElement.insertBefore(range, body);
  }

  public Element getLoopElement(){
    return _loopElement;
  }

  public Element getPragmaElement(){
    return _pragmaElement;
  }

  public Element getBodyElement(){
    // TODO be sure that there is only one body per loop
    NodeList bodies = _loopElement.getElementsByTagName("body");
    Element body = (Element) bodies.item(0);
    return body;
  }

/*
<Var type="Fint" scope="local">i</Var>
<indexRange>
  <lowerBound>
    <FintConstant type="Fint">1</FintConstant>
  </lowerBound>
  <upperBound>
    <FintConstant type="Fint">10</FintConstant>
  </upperBound>
  <step>
    <FintConstant type="Fint">1</FintConstant>
  </step>
</indexRange>
*/

  public String getIterationVariableValue(){
    return _iterationVar;
  }

  public String getLowerBoundValue(){
    return _lowerBoundValue;
  }

  public String getUpperBoundValue(){
    return _upperBoundValue;
  }

  public String getStepValue(){
    return _stepValue;
  }

  public String getFormattedRange(){
    return _iterationVar + "=" + _lowerBoundValue + "," + _upperBoundValue + ","
      + _stepValue;
  }

  public boolean hasSameRangeWith(CLAWloop otherLoop){
    return _lowerBoundValue == otherLoop.getLowerBoundValue() &&
           _upperBoundValue == otherLoop.getUpperBoundValue() &&
           _stepValue == otherLoop.getStepValue() &&
           _iterationVar == otherLoop.getIterationVariableValue();
  }

  public Element getRangeElement(){
    return _rangeElement;
  }

  public Element getRangeVarElement(){
    return _rangeVarElement;
  }


}

@@ -1368,668 +1368,8 @@
  %7D%0A%0A
-  private void setRangeValue(String tag, String newValue)%7B%0A    NodeList rangeElements = _loopElement.getElementsByTagName(tag);%0A    Element rangeElement = (Element) rangeElements.item(0);%0A    NodeList constants = rangeElement.getElementsByTagName(%22FintConstant%22);%0A    Element constant = (Element) constants.item(0);%0A    constant.setTextContent(newValue);%0A  %7D%0A%0A  public void setNewRange(String iterationVariable, String lowerBound,%0A    String upperBound, String step)%7B%0A      _rangeVarElement.setTextContent(iterationVariable);%0A      setRangeValue(%22lowerBound%22, lowerBound);%0A      setRangeValue(%22upperBound%22, upperBound);%0A      setRangeValue(%22step%22, step);%0A  %7D%0A%0A
   pu
@@ -1542,16 +1542,71 @@
  body);%0A
+    _rangeVarElement = var;%0A    _rangeElement = range;%0A
   %7D%0A%0A  p

Save the new var and range element