package org.openrosa.client.view;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.openrosa.client.Context;
import org.openrosa.client.model.IFormElement;
import org.openrosa.client.model.ItextModel;
import org.openrosa.client.model.QuestionDef;
import org.openrosa.client.util.Itext;
import org.openrosa.client.util.ItextLocale;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FocusListener;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HasHorizontalAlignment.HorizontalAlignmentConstant;
public class QuestionItextView extends Composite {
private FlexTable widgetTable = new FlexTable();
private FlexTable layoutTable = new FlexTable();
// private Button addLanguageButton;
private Button addFormButton;
private Label lblItextID;
private TextBox txtItextID;
/** Current ItextID that we're concerned about **/
private IFormElement currentDef;
private List<String> languages;
private List<String> forms;
private PropertiesView propertiesView;
/**
* Gives the rownumber for the specified language/form row.
* Storage format:
* "language:form" -> int
*
* form is optional, use "langauge" (without ":form" for pure version"
* int shows the row in the flextable where this is located
*
* Should be useful if necessary to reference
* the widgets after they are set.
*/
private HashMap<String, Integer> rowLocations;
public QuestionItextView(PropertiesView propertiesView){
this.propertiesView = propertiesView;
initButtonsAndLabels();
// layoutTable.setWidget(0, 0, addLanguageButton);
layoutTable.setWidget(0, 0, addFormButton);
layoutTable.setWidget(0, 1, lblItextID);
layoutTable.setWidget(0, 2, txtItextID);
layoutTable.setWidget(1, 0, widgetTable);
layoutTable.getFlexCellFormatter().setColSpan(1, 0, 2);
rowLocations = new HashMap<String, Integer>();
widgetTable.clear();
languages = new ArrayList<String>();
forms = new ArrayList<String>();
//HIDE ITEXT ID TEXTBOX
lblItextID.setVisible(false);
txtItextID.setVisible(false);
///////////////////////
initWidget(layoutTable);
}
private void init(IFormElement def){
rowLocations = new HashMap<String, Integer>();
widgetTable.clear();
languages = new ArrayList<String>();
forms = new ArrayList<String>();
txtItextID.setValue(def.getItextId());
findAndAddAvailableLangs();
findAndAddAvailableForms();
refreshRows();
}
public void update(){
propertiesView.update();
}
public void setItemID(IFormElement def){
GWT.log("setting ItemID currentDef.getItextId()="+def.getItextId()+" QuestionItextView:90");
if(def == null){
currentDef = null;
txtItextID.setText("");
clearRows();
return;
}else if(def.getItextId() == null){
def.setItextId(def.getQuestionID());
}
currentDef = def;
init(def);
}
private void clearRows(){
widgetTable.clear(); //clear the row and re-add everything so that widgets are added in the right order
widgetTable.clear(true);
clearTableOfSeperatorStyle();
widgetTable.removeAllRows();
rowLocations = new HashMap<String, Integer>();
}
private void refreshRows(){
clearRows();
//assumes that all changes were handled correctly/saved by the textbox listeners.
int rowIndex = 0;
for(String lang:languages){
addDefaultTextAndHintRows(lang,rowIndex);
rowIndex+=2; //two rows were added above
for (String f:forms){
if(currentDef == null){ continue; }
addRow(lang, f, rowIndex);
rowIndex++;
}
addSeperator(rowIndex);
rowIndex++;
}
}
/**
* Adds the default (as in, no special text form)
* and the "hint" form rows.
*/
private void addDefaultTextAndHintRows(String lang, int rowIndex){
addRow(lang,null,rowIndex);
}
/**
* Adds a seperator in the widget table to help
* the user visually distinguis between languages.
* @param rowIndex
*/
private void addSeperator(int rowIndex){
widgetTable.setText(rowIndex, 0, "");
// widgetTable.setWidget(rowIndex, 0, new Label("---"));
widgetTable.getFlexCellFormatter().setStyleName(rowIndex, 0, "itextTabSeperator");
widgetTable.setWidget(rowIndex, 1, new Label(""));
widgetTable.getFlexCellFormatter().setStyleName(rowIndex, 1, "itextTabSeperator");
}
private void clearTableOfSeperatorStyle(){
for(int i=0;i<widgetTable.getRowCount();i++){
for(int j=0;j<widgetTable.getCellCount(i);j++){
widgetTable.getFlexCellFormatter().removeStyleName(i, j, "itextTabSeperator");
}
}
}
/**
* Finds all the available locales based on data from Itext class,
* adds it to this widget's concept of which locales are available for editing.
*/
private void findAndAddAvailableLangs(){
List<ItextLocale> locales = Itext.locales;
for (int i=0;i<locales.size();i++){
languages.add(locales.get(i).getName());
}
}
/**
* Finds all the available forms
* for the current ItemItextID
* and adds them to the pool of known TextForms.
*/
private void findAndAddAvailableForms(){
for(ItextLocale locale: Itext.locales){
mergeForms(locale.getAvailableForms(currentDef.getItextId()));
}
}
/**
* Adds a new language row to this itext view.
* (creates a new locale in Itext.java if necessary)
*
* loops through all the existing languages in this view
* and appends the form based rows to them (if any exist)
* @param name
*/
public void addLanguage(String language){
if(currentDef.getItextId() == null)return;
languages.add(language);
refreshRows();
}
/**
* Adds a new "lang:form" row under each respective language row
*
* ONLY CALL ME IF THERE IS ALREADY AT LEAST ONE LANGUAGE ROW
* @param form
*/
public void addForm(String form){
if(currentDef.getItextId() == null)return;
forms.add(form);
refreshRows();
}
/**
* takes in an ArrayList of available forms (returned by ItextLocale) and
* merges it into this View's list of available forms
* @param newForms
*/
private void mergeForms(ArrayList<String> newForms){
for(String f: newForms){
if(forms.contains(f)) continue;
else forms.add(f);
}
}
private void addRow(String language, String Form, int rowNumber){
GWT.log("adding textRow:QuestionItextView:207, currentDef.getItextId()="+currentDef.getItextId()+"; form="+Form);
final String lang = language;
final String form = Form; //this final business is to use the anon inner class below
final TextBox textBoxWidget = new TextBox();
String fullText = (form == null) ? lang : (lang + ";" + form);
if(rowLocations.containsKey(fullText)) return; //don't want to duplicate rows.
Label labelWidget = new Label(fullText);
//set the default val for the textbox
String itextValue = Itext.getLocale(language).getTranslation(((form == null) ? currentDef.getItextId() : (currentDef.getItextId() + ";" + form)));
if(itextValue == null){
itextValue = "";
}
textBoxWidget.setText(itextValue);
textBoxWidget.addKeyUpHandler(new KeyUpHandler() {
@Override
public void onKeyUp(KeyUpEvent event) {
Itext.addText(lang, ((form == null) ? currentDef.getItextId() : (currentDef.getItextId() + ";" + form)), textBoxWidget.getText()); //handles creating new itext data
update();
}
});
textBoxWidget.addBlurHandler(new BlurHandler() {
@Override
public void onBlur(BlurEvent event) {
Itext.addText(lang, ((form == null) ? currentDef.getItextId() : (currentDef.getItextId() + ";" + form)), textBoxWidget.getText()); //handles creating new itext data
update();
}
});
//populate the flex table
widgetTable.setWidget(rowNumber, 0, labelWidget);
widgetTable.setWidget(rowNumber, 1, textBoxWidget);
//cosmetic things
widgetTable.getFlexCellFormatter().removeStyleName(rowNumber, 0, "itextTabSeperator");
widgetTable.getFlexCellFormatter().removeStyleName(rowNumber, 1, "itextTabSeperator");
rowLocations.put(fullText, rowNumber); //in case we need to reference back at this.
}
/**
* Sets up the addLanguage and addForm buttons
* to have dialogue boxes pop up and all that.
*/
private void initButtonsAndLabels(){
currentDef = null;
addFormButton = new Button("Add a new TextForm");
lblItextID = new Label("ItextID:");
txtItextID = new TextBox();
txtItextID.addKeyUpHandler(new KeyUpHandler() {
public void onKeyUp(KeyUpEvent event) {
updateItextID();
}
});
txtItextID.addBlurHandler(new BlurHandler() {
public void onBlur(BlurEvent event) {
updateItextID();
}
});
addFormButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
String newForm = Window.prompt("Please enter the name of the new TextForm you would like to edit", "long/short/etc");
addForm(newForm);
}
});
}
private void updateItextID(){
if(currentDef == null){
return;
}
String newID = txtItextID.getText();
String currentID = currentDef.getItextId();
if(!newID.equals(currentID)){
currentDef.setItextId(newID);
Itext.renameID(currentID, newID);
}
}
}