package com.redspr.redquerybuilder.core.client.expression;
import java.util.List;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
import com.redspr.redquerybuilder.core.client.BaseSqlWidget;
import com.redspr.redquerybuilder.core.client.Visitor;
import com.redspr.redquerybuilder.core.client.engine.Session;
import com.redspr.redquerybuilder.core.client.util.XWidget;
/**
* An 'and' or 'or' condition as in WHERE ID=1 AND NAME=?
*/
public class ConditionAndOr extends Condition {
interface MyUiBinder extends UiBinder<Widget, ConditionAndOr> {
}
private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
@UiField
XWidget<Expression> left;
@UiField
XWidget<Expression> right;
@UiField
ListBox op;
/**
* The AND condition type as in ID=1 AND NAME='Hello'.
*/
public static final int AND = 0;
/**
* The OR condition type as in ID=1 OR NAME='Hello'.
*/
public static final int OR = 1;
private int andOrType;
public ConditionAndOr(Session session, int andOrType2, Expression left2, Expression right2) {
super(session);
initWidget(uiBinder.createAndBindUi(this));
this.andOrType = andOrType2;
setLeft(left2);
setRight(right2);
op.addItem("AND");
op.addItem("OR");
op.setSelectedIndex(andOrType2);
}
public Expression getLeft() {
return left.getValue();
}
public void setLeft(Expression e) {
left.setValue(e);
}
public Expression getRight() {
return right.getValue();
}
public void setRight(Expression e) {
right.setValue(e);
}
public String getString() {
switch (andOrType) {
case AND:
return "AND";
case OR:
return "OR";
default:
throw new RuntimeException("andOrType=" + andOrType);
}
}
@Override
public String getSQL(List args) {
String sql;
switch (andOrType) {
case AND:
sql = getLeft().getSQL(args) + " AND " + getRight().getSQL(args);
break;
case OR:
sql = getLeft().getSQL(args) + " OR " + getRight().getSQL(args);
break;
default:
throw new RuntimeException("andOrType=" + andOrType);
}
return "(" + sql + ")";
}
@Override
public BaseSqlWidget remove(Expression e) {
BaseSqlWidget parent = getParentExpression();
if (getLeft() == e) {
parent.replace(this, getRight());
} else if (getRight() == e) {
parent.replace(this, getLeft());
} else {
throw new IllegalArgumentException();
}
return parent;
}
@Override
public void replace(Expression a, Expression b) {
if (getLeft() == a) {
setLeft(b);
} else if (getRight() == a) {
setRight(b);
}
}
@Override
public void acceptChildren(Visitor callback) {
getLeft().traverse(callback);
getRight().traverse(callback);
}
@UiHandler("op")
void handleChange(ChangeEvent e) {
andOrType = op.getSelectedIndex();
fireDirty();
}
@Override
public int hook() {
return (getLeft().hook() + getRight().hook()) / 2;
}
@Override
public void onDirty() {
Scheduler.get().scheduleFixedDelay(new RepeatingCommand() {
@Override
public boolean execute() {
Element opOuter = op.getElement().getParentElement();
Element outerDiv = opOuter.getParentElement();
Element topDiv = outerDiv.getFirstChildElement();
int middleOffset = (hook() - getAbsoluteTop()) - opOuter.getOffsetHeight() / 2;
opOuter.getStyle().setTop(middleOffset, Unit.PX);
int leftHook = getLeft().hook();
int rightHook = getRight().hook();
int borderWidth = 10;
int h = rightHook - leftHook - borderWidth;
int top = leftHook - getAbsoluteTop() - borderWidth / 2;
topDiv.getStyle().setHeight(h, Unit.PX);
topDiv.getStyle().setTop(top, Unit.PX);
return false;
}
}, 30);
}
}