/*
 *  ruleConditions.java
 * 
 *  RELOAD Editor - An IMS Metadata, Content Packaging and Learning Design tool 
 *  with ADAPTATION AT ACTIVITY LEVEL
 *
 *  Copyright (c) 2006 Miguel Fernandez Lores
 *
 *  Technical Contact:
 *  Miguel Fern�ndez Lores
 *  e-mail: tucias@hotmail.com
 *
 */

package uk.ac.reload.editor.scormadaptive.rules.jdom.rule;

import uk.ac.reload.editor.scormadaptive.rules.AdaptiveRules_EditorDialog;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.jdom.Attribute;
import org.jdom.Element;

/**
 * Class that contains the information corresponding to a 
 * ruleConditions element of a PREEXISTING RULE
 *
 * @author  lagar
 * @version 0.2 
 */
public class RuleConditions {
    
    private String sConditionCombination;
    
    private boolean bDefault;
    
    private ArrayList<RuleCondition> oRuleCondition;
    
    private Element oEl;
    
    private String[] sText;
    
    public boolean hasComplex = false;
    
    /** Creates a new instance of ruleConditions */
    public RuleConditions() {
        sConditionCombination = "all";
        bDefault = false;
        oRuleCondition = null;
        oEl = null;
        sText = null;
    }
    
    public RuleConditions(Element El) throws Exception {
        oEl = El;
        
        Attribute oAtt = oEl.getAttribute("default");
        if ((oAtt != null)&&(oAtt.getValue().equals("true"))) {
            sConditionCombination = null;
            bDefault = true;
            sText = new String[1];
            sText[0] = "else";
            oRuleCondition = null;
        }
        else {
            bDefault = false;
            List oRClist = oEl.getChildren("ruleCondition"); //ruleCondition
            oAtt = oEl.getAttribute("conditionCombination");
            //Debe haber al menos un hijo ruleCondition
            if (oRClist == null) {
                 throw new Exception("ruleConditions: Child Elements <ruleCondition>" +
                         " is mandatory");
            }
            if (oAtt == null) sConditionCombination = "all";
            else sConditionCombination = oAtt.getValue();
            
            Iterator oItt = oRClist.iterator();
            while (oItt.hasNext()){
                 Element oElAux= (Element)oItt.next();                
                 RuleCondition oRC1 = readTreeRule(oElAux);           
                 addRuleCondition(oRC1);
            }
            
            sText = new String[oRuleCondition.size() + 1];
            sText[0] = "if ";
            int iLast = 0;
            
            for (int i=0; i<oRuleCondition.size(); i++) {
                if (sText[iLast] == null) {
                    sText[iLast] = AdaptiveRules_EditorDialog.sTAB;
                    if (sConditionCombination == "all") sText[iLast] += "and ";
                    else sText[iLast] += "or ";
                }

                if (i < oRuleCondition.size()-1) {
                    if ((oRuleCondition.get(i).getText().contains(".k.")) && (oRuleCondition.get(i+1).getText().contains(".k."))) {
                        String sComplex = getTextComplex (oRuleCondition.get(i).getText(), oRuleCondition.get(i+1).getText());
                        sText[iLast] += sComplex;
                        i++;
                        hasComplex = true;
                    }
                    else sText[iLast] += oRuleCondition.get(i).getText();
                }
                else sText[iLast] += oRuleCondition.get(i).getText();
                iLast++;
                
            }
            
            if (iLast > 1) {
                String sAux = sText[0].substring(3);
                sText[0] = "if (" + sAux; 
                sText[iLast -1] += ")";
            }
            sText[iLast] = "then";
        }
    }
    
    public void setOperatorLast(String sOperator){
        //Esto es para cuando se pulsa NOT
        //Solo afecta al �ltimo ruleCondition introducido
        //=> size()-1
        oRuleCondition.get(oRuleCondition.size()-1).setOperator(sOperator);
    }
    
    public String getOperatorLast(){
        return oRuleCondition.get(oRuleCondition.size()-1).getOperator();
    }
    
    public void addRuleCondition(RuleCondition orC) {
        if (oRuleCondition == null) {
            oRuleCondition = new ArrayList<RuleCondition>();
            oRuleCondition.add(orC);
        } else oRuleCondition.add(orC);
    }
    
    public void deleteRuleCondition(int iIndex) {
        oRuleCondition.remove(iIndex);
    }
    
    public void deleteLastRuleCondition(){
        oRuleCondition.remove(oRuleCondition.size()-1);
    }
    
    public String[] getText(){
        return sText;
    }
    
    public RuleCondition readTreeRule (Element oEl) throws Exception {
        String sOp;
        
        Attribute oAtt = oEl.getAttribute("operator");
        if (oAtt == null) sOp = "noOp";
        else sOp = oAtt.getValue();
        Element oElAC = oEl.getChild("adaptationParameter");
        Element oElComp = oEl.getChild("comparative");
        if ((oElAC == null)||(oElComp == null)) {
             throw new Exception("ruleConditions: Elements <adaptationParameter>" +
                     "and <comparative> are mandatory");
        }
        oAtt = oElComp.getAttribute("comparator");
        if (oAtt == null) {
             throw new Exception("ruleConditions: Attribute comparator is mandatory");
        }
        Element oElSource = oElAC.getChild("source");
        Element oElValue = oElAC.getChild("value");
        if ((oElSource == null)||(oElValue == null)) {
            throw new Exception("ruleConditions: Elements <source>" +
                     "and <value> are mandatory");
        }
        
        adaptationCriterion oAC = new adaptationCriterion(oElValue.getText(), oElSource.getText());
        RuleCondition oRC = new RuleCondition(oAC,oAtt.getValue(),oElComp.getText(), sOp);
        
        return oRC;
    }
    
    public boolean isDefault(){
        return bDefault;
    }
    
    public void setConditionCombination (String sCC){
        sConditionCombination = sCC;
    }
    
    public String getConditionCombination() {
        return sConditionCombination;
    }
    
    public RuleCondition getRuleCondition(int iIndex){
        return oRuleCondition.get(iIndex);
    }
    
    public int getRuleConditionsSize(){
        return oRuleCondition.size();
    }
    
    public Element getElement(int iIndex){
  
        RuleCondition oRC = oRuleCondition.get(iIndex);
        Element oEl = oRC.getElement();
       
        return oEl;
    }

    private String getTextComplex(String sComplex1, String sComplex2) {
        String sResult = "";
        String sPrefix = "";
        String sSufix = "";
        String sOp = "";
        String sValue = "";
        int iSufixBegin = -1;
        int i;
        
        char[] cComplex1 = sComplex1.toCharArray();
        char[] cComplex2 = sComplex2.toCharArray();
        
        for  (i = 0; i < cComplex1.length - 3; i++){
            if ((cComplex1[i] == '=') && (cComplex1[i+1] == '=') && (cComplex1[i+2] == ' ')) {
                sPrefix = sComplex1.substring(i+3, cComplex1.length-1);
                i = cComplex1.length;
            }
        }
        for (i = 0; i< cComplex2.length - 2; i ++){
            if ((cComplex2[i] == '.') && (cComplex2[i+1] == 'k') && (cComplex2[i+2] == '.')) {
                iSufixBegin = i+3;
            }
            if (cComplex2[i] == ' ') {
                sSufix = sComplex2.substring(iSufixBegin, i);
                sOp = sComplex2.substring(i+1, i+3);
                sValue = sComplex2.substring(i+3, cComplex2.length-1);
                i = cComplex2.length;
            }
        }
        
        sResult = "(" + sPrefix + "." + sSufix + " " + sOp + " " + sValue + ")";
        return sResult;
    }
}
