package com.tilisty.views;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import com.tilisty.models.TiProperty;
import com.tilisty.models.TiViewModel;
/**
* The Property views, Maps the key and value
* of a TiProperty to JavaFX views.
*
* The property key maps to a Label
* The value maps to an TextField to allow for editing.
*
* If the value changes, it updates the TiProperty instance
* which should trigger the change event and cause a message
* to be sent to the devices.
*
* @author Jason Simpson <jsnsimpson@gmail.com>
* @version 1.0
*/
public class TiPropertyView {
private TiViewModel view;
private TiProperty prop;
private Label propKey;
private TextField field;
private Pattern ints = Pattern.compile("\\d+");
public TiPropertyView(TiProperty prop, TiViewModel view) {
this.prop = prop;
this.setupPropertyView();
}
/**
* Sets up the property views and the listeners on the property.
* In this listener, we update the TiProperty instance.
*/
private void setupPropertyView() {
this.propKey = new Label(this.prop.getKey());
//set the font, if it is an object type (has sub properties) then make it bold like a header.
if(this.prop.getPropertyType() == TiProperty.PROPERTY_TYPE_OBJECT) {
this.propKey.setFont(Font.font("Arial", FontWeight.BOLD, 14));
} else {
this.propKey.setFont(Font.font("Arial", FontWeight.NORMAL, 14));
}
this.field = new TextField(this.prop.getValue());
field.setPrefWidth(250);
field.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> arg0, String oldValue, String newValue) {
TiPropertyView.this.prop.setValue(newValue);
}
});
field.setOnKeyPressed( new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
if(prop.getPropertyType() == TiProperty.PROPERTY_TYPE_NORMAL) {
if(event.getCode() == KeyCode.UP) {
this.incrOrDecr(true);
} else if(event.getCode() == KeyCode.DOWN) {
this.incrOrDecr(false);
}
}
}
public void incrOrDecr(boolean incr) {
TiPropertyView that = TiPropertyView.this;
TiProperty prop = TiPropertyView.this.prop;
try {
Matcher match = that.ints.matcher(prop.getValue());
match.find();
if(match.group().length() > 0) {
int newDigit = Integer.parseInt(match.group());
if(incr) {
newDigit += 1;
} else {
newDigit -= 1;
}
String newValue = prop.getValue().replace(match.group(), String.valueOf(newDigit));
prop.setValue(newValue);
field.setText(prop.getValue());
}
} catch(NumberFormatException e) {
// System.out.println("Can't use arrows on non-numeric fields");
} catch(IllegalStateException e) {
// System.out.println("Can't use arrows on non-numeric fields");
}
}
});
}
public Label getLabel() {
return this.propKey;
}
public TextField getTextField() {
return this.field;
}
}