package authoritymanager.client;

import java.util.Collection;
import java.util.Iterator;
import java.util.Vector;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CellPanel;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class AddWidget {
	private static final String DEFAULT_WIDGET_HEIGHT	=	"25px" ;
	private String fieldName ;
	public Vector<AddWidget> children ;
	private String configuration ;
	private Widget widget ;
	private AuthorityManagerView view ;
	
	public AddWidget(final AuthorityManagerView view, String configuration) {
		super() ;
		this.view = view ;
		this.configuration = configuration ;
		this.children = new Vector<AddWidget>(1) ;
		this.fieldName = "" ;
		
		String [] st = split(configuration, '.') ; // configuration.split(".") ;
		if (!st [0].trim().equals("*")) {
			this.fieldName = st [0].trim() ;
		}
		else {
			this.fieldName = "" ;
		}
		int indexContent = st [1].indexOf("{") ;
		String content = indexContent == -1 ? "" : st [1].substring(indexContent + 1, st [1].lastIndexOf("}")) ;
		content = content.trim();
		String widgetType = indexContent == -1 ? st [1] : st [1].substring(0, indexContent) ;
		widgetType = widgetType.trim() ;
		String value = st [2].trim() ;
		if (value.equals("*")) {
			value = "" ;
		}
		String width = st [3].trim() ;
		if (width.equals("*")) {
			width = "" ;
		}
		else {
			width = width + "px" ;
		}
		if (widgetType.equals("edit")) {
			TextBox textBox = new TextBox() ;
			if (!width.equals("")) {
				textBox.setWidth(width) ;
			}
			textBox.setText(value) ;
			textBox.setHeight(DEFAULT_WIDGET_HEIGHT) ;
			widget = textBox ;
		}
		else {
			if (widgetType.equals("label")) {
				Label label = new Label(value) ;
				if (!width.equals("")) {
					label.setWidth(width) ;
				}
				label.setHeight(DEFAULT_WIDGET_HEIGHT) ;
				widget = label ;
			}
			else {
				if (widgetType.equals("+")) {
					FlexTable table = new FlexTable() ;					
					widget = table ;
					this.fieldName = "" ;
					final String confChild = st [0] + ".hpanel{" + content + "}.*." + st [3] ;
					final AddWidget child = new AddWidget(view, confChild) ;
					children.add(child) ;
					table.setWidget(0, 0, child.getWidget()) ;
					if (!width.equals("")) {
						table.getCellFormatter().setWidth(0, 0, width) ;
					}
					AddButton btnAdd = new AddButton(child, this.children) ;
					table.setWidget(0, 1, btnAdd) ;
				}
				else {
					if (widgetType.equals("hpanel") || widgetType.equals("vpanel")) {
						Panel panel = widgetType.equals("vpanel") ? new VerticalPanel() : new HorizontalPanel() ;
						widget = panel ;
						if (panel instanceof HorizontalPanel) {
							((HorizontalPanel) panel).setSpacing(3) ;
						}
						if (panel instanceof VerticalPanel) {
							((VerticalPanel) panel).setSpacing(1) ;
						}
						
						if (!width.equals("")) {
							panel.setWidth(width) ;
						}
						String [] stChild = split(content, ',') ; //content.split(",") ;
						for (int iChild = 0 ; iChild < stChild.length ; iChild ++) {
							String confChild = stChild [iChild].trim() ;
							AddWidget widgetChild = new AddWidget(view, confChild) ;
							children.add(widgetChild) ;
							panel.add(widgetChild.getWidget()) ;
						}
					}
					else {
						if (widgetType.equals("list")) {
							final ListBox list = new ListBox() ;
							list.setHeight(DEFAULT_WIDGET_HEIGHT) ;
							widget = list ;
							if (!width.equals("")) {
								list.setWidth(width) ;
							}
							String [] stContent = content.split("://") ;
							String location = stContent [0].trim().toUpperCase() ;
							
							if (location.equals("URL")) {
								String fileName = stContent [1]	;
								AsyncCallback<String> callback = new AsyncCallback<String>() {
									public void onFailure(Throwable caught) {
									}
									public void onSuccess(String result) {
										String [] values = result.split("\n") ;
										for (int iValue = 0 ; iValue < values.length ; iValue ++) {
											list.addItem(values [iValue].trim()) ;
										}
									}
								} ;	
								view.getController().getFile(fileName, callback) ;
							}
							if (location.equals("DATA")) {
								String [] values = stContent [1].split(",") ;
								for (int iValue = 0 ; iValue < values.length ; iValue ++) {
									list.addItem(values [iValue].trim()) ;
								}
							}
						}
					}
				}
			}
		}
	}
	
	private String [] split(String s, char delim) {
		Vector<String> res = new Vector<String>(4) ;
		int left = 0, curRes = 0 ;
		String current = "" ;
		for (int i = 0 ; i < s.length() ; i ++) {
			current += s.charAt(i) ;
			if (s.charAt(i) == '{') {
				left ++ ;
			}
			if (s.charAt(i) == '}') {
				left -- ;
			}
			if (s.charAt(i) == delim && left == 0) {
				res.add(current.substring(0, current.length() - 1)) ;
				current = "" ;
			}
		}
		res.add(current) ;
		String [] result = new String [res.size()] ;
		res.toArray(result) ;
		return result ;
	}
	public void Disable() {
		if (widget instanceof TextBox) {
			((TextBox) widget).setEnabled(false) ;
		} else
		if (widget instanceof ListBox) {
			((ListBox) widget).setEnabled(false) ;
		} else
		if (widget instanceof FlexTable) {
			for (AddWidget addWidget: children) {
				addWidget.Disable() ;
			}
		} else
		if (widget instanceof Panel) {
			for (AddWidget addWidget: children) {
				addWidget.Disable() ;
			}
		}
		
	}
	
	public void Reset() {
		if (widget instanceof TextBox) {
			((TextBox) widget).setText("") ;
		} else
		if (widget instanceof ListBox) {
			((ListBox) widget).setSelectedIndex(0) ;
		} else
		if (widget instanceof FlexTable) {
			FlexTable table = (FlexTable) widget ;
			for (int iRow = table.getRowCount() - 2 ; iRow >= 0 ; iRow --) {
				table.removeRow(iRow) ;
				((Vector) children).remove(iRow) ;
			}
			for (AddWidget addWidget: children) {
				addWidget.Reset() ;
			}
		} else
		if (widget instanceof Panel) {
			for (AddWidget addWidget: children) {
				addWidget.Reset() ;
			}
		}
		
	}
	public void addChild(AddWidget addWidget) {
		if (widget instanceof CellPanel) {
			((Panel) widget).add(addWidget.getWidget()) ;
		}
		children.add(addWidget) ;
	}
	
	public Widget getWidget() {
		return widget ;
	}
	
	public DataSerial toDataSerial() {
		DataSerial dataSerial = new DataSerial() ;
		this.toDataSerial(dataSerial) ;
		return dataSerial ;
	}
	
	public void toDataSerial(DataSerial dataSerial) {
		if (widget != null) {
			if (widget instanceof TextBox) {
				TextBox textBox = (TextBox) widget ;
				if (textBox.getText().length() > 0) {
					dataSerial.put(fieldName, textBox.getText()) ;
				}
			} else
			if (widget instanceof ListBox) {
				ListBox listBox = (ListBox) widget ;
				dataSerial.put(fieldName, listBox.getValue(listBox.getSelectedIndex())) ;
			} else
			if (widget instanceof FlexTable) {
				DataSerial subData = null ;
				if (!fieldName.equals("")) {
					subData = new DataSerial() ;
				}
				for (int iChild = 0 ; iChild < children.size() - 1; iChild ++) {
					AddWidget child = children.get(iChild) ;
					if (subData != null) {
						child.toDataSerial(subData) ;
					}
					else {
						child.toDataSerial(dataSerial) ;
					}
				}
				if (subData != null && children.size() > 1) {
					dataSerial.put(fieldName, subData) ;
				}
				
			} else
			if (widget instanceof Panel) {
				DataSerial subData = null ;
				if (!fieldName.equals("")) {
					subData = new DataSerial() ;
				}
				for (AddWidget child: children) {
					if (subData != null) {
						child.toDataSerial(subData) ;
					}
					else {
						child.toDataSerial(dataSerial) ;
					}
				}
				if (subData != null) {
					dataSerial.put(fieldName, subData) ;
				}
			}
		}
		
			
	}
	
	public String GetConfiguration() {
		return this.configuration ;
	}
	
	public AuthorityManagerView GetView() {
		return this.view ;
	}
	
}
	
	/*
	 * AsyncCallback<String> callback = new AsyncCallback<String>() {
									public void onFailure(Throwable caught) {
									}
									public void onSuccess(String result) {
										String [] values = result.split("\n") ;
										for (int iValue = 0 ; iValue < values.length ; iValue ++) {
											//list.addItem(values [iValue].trim()) ;
										}
									}
								} ;*/
