/* ************************************************************************
#
#  DivConq
#
#  http://divconq.com/
#
#  Copyright:
#    Copyright 2012 eTimeline, LLC. All rights reserved.
#
#  License:
#    See the license.txt file in the project's top-level directory for details.
#
#  Authors:
#    * Andy White
#
************************************************************************ */
package divconq.script;

import divconq.struct.ScalarStruct;
import divconq.struct.Struct;
import divconq.struct.scalar.BooleanStruct;
import divconq.xml.XElement;

public class LogicBlockInstruction extends BlockInstruction {
    protected boolean checkLogic(StackEntry stack) {
        return checkLogic(stack, this.source);
    }

    protected boolean checkLogic(StackEntry stack, XElement source) {
        if (source == null) 
        	source = this.source;
      
        Struct target = stack.refFromSource(source, "Target");
        
        if (target == null) 
        	stack.queryVariable("_LastState");

        return this.checkLogic(stack, (ScalarStruct)target, source);
    }

    protected boolean checkLogic(StackEntry stack, ScalarStruct target, XElement source) {
        boolean isok = true;
        boolean condFound = false;

        if (source == null) 
        	source = this.source;

		if (isok && source.hasAttribute("Equal")) {
			Struct other = stack.refFromSource(source, "Equal", target.getType());
            isok = (target.compare(other) == 0);  //  (var == iv);
            condFound = true;
        }
		
		if (isok && source.hasAttribute("Equals")) {
			Struct other = stack.refFromSource(source, "Equals", target.getType());
            isok = (target.compare(other) == 0);  //  (var == iv);
            condFound = true;
        }
		
		if (isok && source.hasAttribute("LessThan")) {
			Struct other = stack.refFromSource(source, "LessThan", target.getType());
            isok = (target.compare(other) < 0);  //  (var < iv);
            condFound = true;
        }
		
		if (isok && source.hasAttribute("GreaterThan")) {
			Struct other = stack.refFromSource(source, "GreaterThan", target.getType());
            isok = (target.compare(other) > 0);  //  (var > iv);
            condFound = true;
        }
        
		if (isok && source.hasAttribute("LessThanOrEqual")) {
			Struct other = stack.refFromSource(source, "LessThanOrEqual", target.getType());
            isok = (target.compare(other) <= 0);  //  (var <= iv);
            condFound = true;
        }
		
		if (isok && source.hasAttribute("GreaterThanOrEqual")) {
			Struct other = stack.refFromSource(source, "GreaterThanOrEqual", target.getType());
            isok = (target.compare(other) >= 0);  //  (var >= iv);
            condFound = true;
        }
		
		if (!condFound) {
			isok = false;
			
	        if (target instanceof BooleanStruct) {
	        	Boolean ret = ((BooleanStruct)target).getValue();
	        	
	        	if (ret != null)
	        		isok = ret.booleanValue();
	        }
        }

		if (stack.boolFromSource(source, "Not")) 
			isok = !isok;

        return isok;
    }
}
