package com.fr.design.gui.columnrow;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.JFormattedTextField;
import javax.swing.JPanel;
import javax.swing.JSpinner.DefaultEditor;
import javax.swing.SpinnerListModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;

import com.fr.design.designer.IntervalConstants;
import com.fr.design.event.UIObserver;
import com.fr.design.event.UIObserverListener;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.gui.ispinner.UIBasicSpinner;
import com.fr.design.gui.ispinner.UpperCaseSpinner;
import com.fr.design.gui.ispinner.ColumnRowSpinner;
import com.fr.general.ComparatorUtils;
import com.fr.stable.ColumnRow;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import com.fr.design.utils.gui.GUICoreUtils;

/**
 * the component to edit ColumnRow
 *
 * @editor zhou 2012-3-22下午3:55:53
 */
public class ColumnRowPane extends JPanel implements UIObserver {

	private static final long serialVersionUID = 1L;
	private static String[] columnarray = new String[1000];
	private static String[] rowarray = new String[5000];


	protected UpperCaseSpinner columnSpinner;
	protected UIBasicSpinner rowSpinner;

	static {
		for (int i = 1; i < 1000; i++) {
			columnarray[i - 1] = StableUtils.convertIntToABC(i);
		}
		for (int i = 1; i < 5000; i++) {
			rowarray[i - 1] = StringUtils.EMPTY + i;
		}
	}

	protected DocumentListener d = new DocumentListener() {


		@Override
		public void removeUpdate(DocumentEvent e) {
			String rolText = ((DefaultEditor) columnSpinner.getEditor()).getTextField().getText();
			String rowText = ((DefaultEditor) rowSpinner.getEditor()).getTextField().getText();
			if (rolText == null || rolText.length() == 0 || rowText == null || rowText.length() == 0) {
				return;
			}
			int col = StableUtils.convertABCToInt(rolText) - 1;
			int row = Integer.parseInt(rowText) - 1;
			setColumnRow(ColumnRow.valueOf(col, row));
		}

		@Override
		public void insertUpdate(DocumentEvent e) {
			int col = StableUtils.convertABCToInt(((DefaultEditor) columnSpinner.getEditor()).getTextField().getText()) - 1;
			int row = Integer.parseInt(((DefaultEditor) rowSpinner.getEditor()).getTextField().getText()) - 1;
			setColumnRow(ColumnRow.valueOf(col, row));
		}

		@Override
		public void changedUpdate(DocumentEvent e) {

		}
	};


	private UIObserverListener uiObserverListener;
	private ColumnRow cr;


	public ColumnRowPane() {
		this.initComponents();
		iniListener();
	}


	/**
	 * 初始化元素
	 */
	public void initComponents() {
		this.setLayout(new GridLayout(0, 2, IntervalConstants.INTERVAL_L6, 0));
		initColSpinner();
		this.add(columnSpinner, BorderLayout.WEST);
		initRowSpinner();
		this.add(rowSpinner);
		this.addDocumentListener(d);
	}

	private void iniListener() {
		if (shouldResponseChangeListener()) {
			this.addChangeListener(new ChangeListener() {
				@Override
				public void stateChanged(ChangeEvent e) {
					if (uiObserverListener == null) {
						return;
					}
					uiObserverListener.doChange();
				}
			});
		}
	}


	protected void initRowSpinner() {
		rowSpinner = new ColumnRowSpinner((new SpinnerListModel(rowarray))) {
			public boolean shouldResponseChangeListener() {
				return false;
			}

		};
		rowSpinner.setPreferredSize(new Dimension(60, 24));
		JFormattedTextField rftf = GUICoreUtils.getSpinnerTextField(rowSpinner);
		if (rftf != null) {
			rftf.setColumns(4); // specify more width than we need
			rftf.setHorizontalAlignment(UITextField.LEFT);
		}
	}

	protected void initColSpinner() {
		SpinnerListModel columnSpinnerListModel = new SpinnerListModel(columnarray);
		columnSpinner = new UpperCaseSpinner(columnSpinnerListModel) {
			public boolean shouldResponseChangeListener() {
				return false;
			}
		};
		columnSpinner.setPreferredSize(new Dimension(60, 24));
		JFormattedTextField cftf = GUICoreUtils.getSpinnerTextField(columnSpinner);
		if (cftf != null) {
			cftf.setColumns(3); // specify more width than we need
			cftf.setHorizontalAlignment(UITextField.LEFT);
		}

		((AbstractDocument) cftf.getDocument()).setDocumentFilter(new DocumentFilter() {
			public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {
				fb.insertString(offset, string.toUpperCase(), attr);
			}

			public void replace(FilterBypass fb, int offset, int length, String string, AttributeSet attr) throws BadLocationException {
				if (string != null) {
					string = string.toUpperCase();
				}
				fb.replace(offset, length, string, attr);
			}
		});
	}

	protected void addDocumentListener(DocumentListener l) {
		((DefaultEditor) columnSpinner.getEditor()).getTextField().getDocument().addDocumentListener(l);
		((DefaultEditor) rowSpinner.getEditor()).getTextField().getDocument().addDocumentListener(l);
	}

	private void removeDocumentListener(DocumentListener l) {
		((DefaultEditor) columnSpinner.getEditor()).getTextField().getDocument().removeDocumentListener(l);
		((DefaultEditor) rowSpinner.getEditor()).getTextField().getDocument().removeDocumentListener(l);
	}

	/**
	 * columnSpinner与rowSpinner应该整体考虑，设置ColumnRow应该只触发一次事件
	 *
	 * @param columnRow
	 */
	public void setColumnRow(ColumnRow columnRow) {
		if (!ComparatorUtils.equals(cr, columnRow)) {
			setGlobalName();
			removeDocumentListener(d);
			cr = columnRow;
			addDocumentListener(d);
			fireChanged();
		}
	}

	public void setGlobalName(){

	}

	public void populate(ColumnRow columnRow) {
		cr = columnRow;
		int column = columnRow.getColumn();
		if (column < 0) {
			column = 0;
		}
		removeDocumentListener(d);
		columnSpinner.setValue(StableUtils.convertIntToABC(column + 1));
		int row = columnRow.getRow();
		// shoc 小于0就蹦了
		if (row < 0) {
			row = 0;
		}
		rowSpinner.setValue("" + (row + 1));
		addDocumentListener(d);
		fireChanged();
	}


	public ColumnRow update() {
		return cr;
	}

	/**
	 * 添加一个listener到listenerList中
	 * @param l 监听
	 */
	public void addChangeListener(ChangeListener l) {
		this.listenerList.add(ChangeListener.class, l);
	}

	/**
	 * 从listenerList中移除一个listener
	 * @param l 监听
	 */
	public void removeChangeListener(ChangeListener l) {
		this.listenerList.remove(ChangeListener.class, l);
	}

	// august: Process the listeners last to first
	protected void fireChanged() {
		Object[] listeners = listenerList.getListenerList();

		for (int i = listeners.length - 2; i >= 0; i -= 2) {
			if (listeners[i] == ChangeListener.class) {
				((ChangeListener) listeners[i + 1]).stateChanged(new ChangeEvent(this));
			}
		}
	}

	/**
	 * 给组件登记一个观察者监听事件
	 * @param listener 监听
	 */
	public void registerChangeListener(UIObserverListener listener) {
		uiObserverListener = listener;
	}

	/**
	 * 组件是否需要响应添加的观察者事件
	 * @return 如果需要响应观察者事件则返回true，否则返回false
	 */
	public boolean shouldResponseChangeListener() {
		return true;
	}
}