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

package cx2x.translator.transformer;

import java.util.LinkedHashMap;
import java.util.Map;

import cx2x.translator.transformation.claw.Kcaching;
import cx2x.translator.transformation.loop.*;
import cx2x.translator.transformation.openacc.OpenAccContinuation;
import cx2x.translator.transformation.utility.UtilityRemove;
import cx2x.xcodeml.transformation.*;

/**
 * ClawTransformer stores all transformation groups applied during the
 * translation.
 *
 * @author clementval
 */

public class ClawTransformer implements Transformer {
  private int _transformationCounter = 0;

  // Hold all tranformation groups
  private final Map<Class, TransformationGroup> _tGroups;


  /**
   * ClawTransformer ctor. Creates the transformation groups needed for the CLAW
   * transformation and order the accordingly to their interpretation order.
   */
  public ClawTransformer(){
    /*
     * Use LinkedHashMap to be able to iterate through the map
     * entries with the insertion order.
     */
    _tGroups = new LinkedHashMap<>();
    _tGroups.put(UtilityRemove.class,
        new IndependentTransformationGroup("remove"));
    _tGroups.put(ArrayTransform.class,
        new IndependentTransformationGroup("array-transform"));
    _tGroups.put(Kcaching.class,
        new IndependentTransformationGroup("kcache"));
    _tGroups.put(LoopExtraction.class,
        new IndependentTransformationGroup("loop-extract"));
    _tGroups.put(LoopFusion.class,
        new DependentTransformationGroup("loop-fusion"));
    _tGroups.put(LoopHoist.class,
        new IndependentTransformationGroup("loop-hoist"));
    _tGroups.put(LoopInterchange.class,
        new IndependentTransformationGroup("loop-interchange"));
    _tGroups.put(OpenAccContinuation.class,
        new IndependentTransformationGroup("open-acc-continuation"));
  }

  /**
   * @see Transformer#addTransformation(Transformation)
   */
  public void addTransformation(Transformation t){
    if(_tGroups.containsKey(t.getClass())){
      _tGroups.get(t.getClass()).add(t);
    }
  }

  /**
   * @see Transformer#getGroups()
   */
  public Map<Class, TransformationGroup> getGroups(){
    return _tGroups;
  }

  /**
   * Get the next extraction counter value.
   * @return Transformation counter value.
   */
  public int getNextTransformationCounter(){
    return _transformationCounter++;
  }
}

@@ -132,16 +132,42 @@
 ormer;%0A%0A
+import java.util.HashMap;%0A
 import j
@@ -182,32 +182,32 @@
 .LinkedHashMap;%0A
-
 import java.util
@@ -477,16 +477,87 @@
 ation.*;
+%0Aimport cx2x.xcodeml.xelement.XbaseElement;%0Aimport org.w3c.dom.Element;
 %0A%0A/**%0A *
@@ -862,16 +862,127 @@
 roups;%0A%0A
+  // Hold cross-transformation elements%0A  private final Map%3CElement, XbaseElement%3E _crossTransformationTable;%0A%0A
 %0A  /**%0A 
@@ -1291,16 +1291,91 @@
      */%0A
+    // TODO read configuration from a config file for transformation order%0A
     _tGr
@@ -2193,16 +2193,67 @@
 ion%22));%0A
+%0A%0A    _crossTransformationTable = new HashMap%3C%3E();%0A
   %7D%0A%0A  /
@@ -2730,24 +2730,24 @@
 nCounter()%7B%0A
-
     return _
@@ -2775,10 +2775,941 @@
 ++;%0A  %7D%0A
+%0A%0A  /**%0A   * Get a stored element from a previous transformation.%0A   * @param key Key to use to retrieve the element.%0A   * @return The stored element if present. Null otherwise.%0A   */%0A  public XbaseElement hasElement(XbaseElement key)%7B%0A    if(_crossTransformationTable.containsKey(key.getBaseElement()))%7B%0A      return _crossTransformationTable.get(key.getBaseElement());%0A    %7D%0A    return null;%0A  %7D%0A%0A  /**%0A   * Store a XbaseElement from a transformation for a possible usage in another%0A   * transformation. If a key is already present, the element is overwritten.%0A   * @param key   The element acting as a key.%0A   * @param value The element to be stored.%0A   */%0A  public void storeElement(XbaseElement key, XbaseElement value)%7B%0A    if(_crossTransformationTable.containsKey(key.getBaseElement()))%7B%0A      _crossTransformationTable.remove(key.getBaseElement());%0A    %7D%0A    _crossTransformationTable.put(key.getBaseElement(), value);%0A  %7D%0A
 %7D%0A

Add ability to store information between transformations