/*
 * This file is released under terms of BSD license
 * See LICENSE file for more information
 */

package cx2x.xcodeml.xelement;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.util.ArrayList;
import java.util.List;

import cx2x.xcodeml.helper.*;


/**
 * The XarrayRef represents the FarrayRef (7.4.4) element in XcodeML
 * intermediate representation.
 *
 * Elements:
 * ( varRef, (arrayIndex | indexRange | FarrayConstructor | FarrayRef)* )
 * - Required:
 *   - varRef
 * - Optional:
 *   - arrayIndex TODO
 *   - indexRange TODO
 *   - FarrayConstructor TODO
 *   - FarrayRef TODO (XarrayRef)
 * Attributes:
 * - Optional: type (text)
 *
 * @author clementval
 */

public class XarrayRef extends XbaseElement {

  private String _type = null;
  private XvarRef _varRef = null;
  private List<XbaseElement> _innerElement = null;

  /**
   * Xelement standard ctor. Pass the base element to the base class and read
   * inner information (elements and attributes).
   * @param baseElement The root element of the Xelement
   */
  public XarrayRef(Element baseElement){
    super(baseElement);
    _innerElement = new ArrayList<>();
    readElementInformation();
  }

  /**
   * Get a list of all inner elements.
   * @return A list of XbaseElement.
   */
  public List<XbaseElement> getInnerElements(){
    return _innerElement;
  }

  /**
   *  Read inner element information.
   */
  private void readElementInformation(){
    _type = XelementHelper.getAttributeValue(this,
      XelementName.ATTR_TYPE);

    // Find Var element
    _varRef = XelementHelper.findVarRef(this, false);

    // TODO read all in one loop
    // Read potential arrayIndex
    NodeList nodeList = baseElement.
      getElementsByTagName(XelementName.ARRAY_INDEX);

    for (int i = 0; i < nodeList.getLength(); i++) {
      Node n = nodeList.item(i);
      if (n.getNodeType() == Node.ELEMENT_NODE) {
        Element el = (Element)n;
        XarrayIndex arrayIndex = new XarrayIndex(el);
        _innerElement.add(arrayIndex);
      }
    }

    // TODO read indexRange

    // TODO read FarrayConstructor

    // TODO read FarrayRef

  }

  /**
   * Get the inner varRef object.
   * @return The inner varRef object.
   */
  public XvarRef getVarRef(){
    return _varRef;
  }

  /**
   * Get the arrayRef type value.
   * @return The type value as String. Null if the type value is not set.
   */
  public String getType(){
    return _type;
  }


  /**
   * Set the type attribute of the arrayRef element.
   * @param type Type of the arrayRef.
   */
  public void setType(String type){
    if(baseElement != null){
      baseElement.setAttribute(XelementName.ATTR_TYPE, type);
    }
  }

  /**
   * Append a XbaseElement as the last children of XarrayRef.
   * @param element The element to append.
   */
  public void append(XbaseElement element){
    append(element, false);
  }

  /**
   * Append a XbaseElement as the last children of XarrayRef.
   * @param element       The element to append.
   * @param cloneElement  If true, the element is cloned before being added. If
   *                      false, the element is directly added.
   */
  public void append(XbaseElement element, boolean cloneElement){
    if(cloneElement){
      Node clone = element.cloneNode();
      baseElement.appendChild(clone);
    } else {
      baseElement.appendChild(element.getBaseElement());
    }

    if(element instanceof XvarRef){
      _varRef = (XvarRef)element;
    }
  }

}

@@ -1636,30 +1636,25 @@
 e);%0A%0A    // 
-TODO r
+R
 ead all in o
@@ -1655,115 +1655,232 @@
 l in
- one loop%0A    // Read potential arrayIndex%0A    NodeList nodeList = baseElement.%0A      getE
+ner elements%0A    Node crtNode = baseElement.getFirstChild();%0A    while(crtNode != null)%7B%0A      if (crtNode.getNodeType() == Node.ELEMENT_NODE) %7B%0A        Element element = (Element)crtNode;%0A        switch (e
 lement
-sBy
+.get
 TagName(
 Xele
@@ -1875,16 +1875,35 @@
 TagName(
+))%7B%0A          case 
 Xelement
@@ -1922,180 +1922,341 @@
 NDEX
-);%0A%0A    for (int i = 0; i %3C nodeList.getLength(); i++) %7B%0A      Node n = nodeList.item(i);%0A      if (n.getNodeType() == Node.ELEMENT_NODE) %7B%0A        Element el = (Element)n;
+:%0A            XarrayIndex arrayIndex = new XarrayIndex(element);%0A            _innerElement.add(arrayIndex);%0A            break;%0A          case XelementName.INDEX_RANGE:%0A            XindexRange indexRange = new XindexRange(element);%0A            _innerElement.add(indexRange);%0A            break;%0A          case XelementName.F_ARRAY_REF:
 %0A   
@@ -2260,38 +2260,38 @@
         
+    
 Xarray
-Index
+Ref
  array
-Index
+Ref
  = new X
@@ -2299,19 +2299,26 @@
 rray
-Index(el);%0A
+Ref(element);%0A    
     
@@ -2336,37 +2336,35 @@
 lement.add(array
-Index
+Ref
 );%0A      %7D%0A    %7D
@@ -2360,46 +2360,27 @@
     
-%7D%0A
     
-%7D%0A%0A    // TODO read indexRange%0A%0A
+  break;%0A      
     
@@ -2414,36 +2414,73 @@
 tor%0A
-%0A    // TODO read FarrayRef%0A
+        %7D%0A      %7D%0A      crtNode = crtNode.getNextSibling();%0A    %7D
 %0A  %7D

Read all in one loop