package x2x.translator.xcodeml;

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

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");
  }

  protected void findRangeElements(){
    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"); // TODO string constant
    Element constant = (Element) constants.item(0);
    NodeList vars = rangeElement.getElementsByTagName("Var"); // TODO string constant
    Element var = (Element) constants.item(0);
    if(constant != null){
      return constant.getTextContent();
    }
    if(var != null){
      return var.getTextContent();
    }
    return null; // TODO probably throws an exception
  }

  public void setNewRange(Node var, Node range){
    Element body = getBodyElement();
    Node newVar = var.cloneNode(true);
    Node newRange = range.cloneNode(true);
    _loopElement.insertBefore(newVar, body);
    _loopElement.insertBefore(newRange, body);
    findRangeElements();

    //_rangeVarElement = var;
    //_rangeElement = range;
  }

  public void deleteRangeElements(){
    _loopElement.removeChild(_rangeVarElement);
    _loopElement.removeChild(_rangeElement);
  }

  protected void swapRangeElementsWith(CLAWloop otherLoop){
    otherLoop.setNewRange(_rangeVarElement, _rangeElement);
    setNewRange(otherLoop.getRangeVarElement(), otherLoop.getRangeElement());
  }

  public Element getLoopElement(){
    return _loopElement;
  }

  public Element getPragmaElement(){
    return _pragmaElement;
  }

  public Element getBodyElement(){
    return CLAWelementHelper.getBody(_loopElement);
  }

  public String getOriginalFilename(){
    return CLAWelementHelper
      .getAttributeValue(_pragmaElement, XelementName.ATTR_FILE);
  }

  public String getPragmaLine(){
    return CLAWelementHelper
      .getAttributeValue(_pragmaElement, XelementName.ATTR_LINENO);
  }


/*
<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;
  }


}

@@ -481,16 +481,17 @@
 lue;%0A%0A%0A%0A
+%0A
   public
@@ -594,48 +594,25 @@
     
-NodeList vars = _loopElement.
+findRan
 ge
-t
 Elements
 ByTa
@@ -611,788 +611,242 @@
 ents
-ByTagName(%22Var%22);%0A    Element var = (Element) vars.item(0);%0A    _rangeVarElement = var;%0A    _iterationVar = var.getTextContent();%0A    NodeList ranges = _loopElement.getElementsByTagName(%22indexRange%22);%0A    Element range = (Element) ranges.item(0);%0A    _rangeElement = range;%0A%0A    _lowerBoundValue = getRangeValue(%22lowerBound%22);%0A    _upperBoundValue = getRangeValue(%22upperBound%22);%0A    _stepValue = getRangeValue(%22step%22);%0A  %7D%0A%0A  protected void findRangeElements()%7B%0A    NodeList vars = _loopElement.getElementsByTagName(%22Var%22);%0A    Element var = (Element) vars.item(0);%0A    _rangeVarElement = var;%0A    _iterationVar = var.getTextContent();%0A    NodeList ranges = _loopElement.getElementsByTagName(%22indexRange%22);%0A    Element range = (Element) ranges.item(0);%0A    _rangeElement = range;%0A
+();%0A  %7D%0A%0A  protected void findRangeElements()%7B%0A    _rangeVarElement = CLAWelementHelper.findVar(_loopElement);%0A    _rangeElement = CLAWelementHelper.findIndexRange(_loopElement);%0A%0A    _iterationVar = _rangeVarElement.getTextContent();
 %0A   
@@ -1930,68 +1930,8 @@
 s();
-%0A%0A    //_rangeVarElement = var;%0A    //_rangeElement = range;
 %0A  %7D

Refactor some duplicated code