package org.nybatis.core.db.sql.sqlNode.element.abstracts;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.nybatis.core.db.session.executor.util.QueryParameter;
import org.nybatis.core.db.sql.sqlNode.element.ElseIfSqlElement;
import org.nybatis.core.db.sql.sqlNode.element.ElseSqlElement;
import org.nybatis.core.db.sql.sqlNode.element.IfSqlElement;
import org.nybatis.core.db.sql.sqlNode.element.WhenSqlElement;
import org.nybatis.core.exception.unchecked.SqlParseException;
import org.nybatis.core.model.NMap;


public abstract class SqlElement {

    protected List<SqlElement> children = new ArrayList<>();

	public String toString( QueryParameter param ) throws SqlParseException {

		StringBuilder sb = new StringBuilder();

		for( ElementText element : toStringList( param ) ) {
			sb.append( element.getText() );
		}

		return sb.toString();

	}

	public void append( SqlElement sqlElement ) {
		children.add( sqlElement );
	}

	public List<SqlElement> children() {
		return children;
	}

	protected List<ElementText> toStringList( QueryParameter param ) {

		List<ElementText> list = new ArrayList<>();

		Boolean previousCondition = null;

		for( SqlElement element : children ) {

			if( isElseSeries(element) ) {
				if( previousCondition != null && previousCondition != true ) {
					list.add( new ElementText( element.getClass(), element.toString( param ) ) );
				}
			} else {
				list.add( new ElementText( element.getClass(), element.toString( param ) ) );
			}

			if( isIfSeries(element) ) {
				if( previousCondition == null || previousCondition == false ) {
					previousCondition = getIfSeriesResult( element, param );
				}
			}

			if( isIfCloseSeries(element) ) {
				previousCondition = null;
			}

		}

		return list;

	}

	private boolean isIfSeries( SqlElement element ) {
		return element instanceof IfSqlElement;
	}

	private boolean getIfSeriesResult( SqlElement element, QueryParameter param ) {

		if( ! isIfSeries(element) ) return false;

		return ((IfSqlElement) element).isTrue( param );

	}

	private boolean isElseSeries( SqlElement element ) {

		Class klass = element.getClass();

		if( klass == ElseIfSqlElement.class ) return true;
		if( klass == WhenSqlElement.class   ) return true;
		return klass == ElseSqlElement.class;

	}

	private boolean isIfCloseSeries( SqlElement element ) {
		return element instanceof ElseSqlElement;
	}

}
@@ -107,30 +107,8 @@
 ist;
-%0Aimport java.util.Map;
 %0A%0Aim
@@ -489,45 +489,8 @@
 on;%0A
-import org.nybatis.core.model.NMap;%0A%0A
 %0Apub
@@ -1460,30 +1460,24 @@
 %0A%09%09%09if( isIf
-Series
 (element) ) 
@@ -1470,32 +1470,132 @@
 If(element) ) %7B%0A
+%09%09%09%09previousCondition = getIfSeriesResult( element, param );%0A%0A%09%09%09%7D else if( isElseIf( element ) ) %7B%0A
 %09%09%09%09if( previous
@@ -1718,44 +1718,39 @@
 %09%09%7D%0A
+%0A
 %09%09%09%7D
-%0A%0A%09%09%09if( isIfCloseSeries(
+ else if( isElse( 
 element
+ 
 ) ) 
@@ -1837,69 +1837,280 @@
 isIf
-Series( SqlElement element ) %7B%0A%09%09return element instanceof If
+( SqlElement element ) %7B%0A%09%09return element.getClass() == IfSqlElement.class;%0A%09%7D%0A%0A%09private boolean isElseIf( SqlElement element ) %7B%0A%09%09return element.getClass() == ElseIfSqlElement.class;%0A%09%7D%0A%0A%09private boolean isElse( SqlElement element ) %7B%0A%09%09return element.getClass() == Else
 SqlE
@@ -2111,24 +2111,30 @@
 seSqlElement
+.class
 ;%0A%09%7D%0A%0A%09priva
@@ -2208,17 +2208,16 @@
 ram ) %7B%0A
-%0A
 %09%09if( ! 
@@ -2220,30 +2220,26 @@
 ( ! isIf
-Series
 (
+ 
 element
+ 
 ) ) retu
@@ -2248,17 +2248,16 @@
  false;%0A
-%0A
 %09%09return
@@ -2299,17 +2299,16 @@
 aram );%0A
-%0A
 %09%7D%0A%0A%09pri
@@ -2550,110 +2550,5 @@
 %09%7D%0A%0A
-%09private boolean isIfCloseSeries( SqlElement element ) %7B%0A%09%09return element instanceof ElseSqlElement;%0A%09%7D%0A%0A
 %7D

fix abnormal working of [else/elseif] sql node .