/**
 * Moxkiriya standalone Wiki.
 * Select party dialog controller.
 * 
 * @author Ryuhei Terada
 * See the '<a href="{@docRoot}/copyright.html">Copyright</a>'
 */package com.wiki.standalone.moxkiriya.dialog;

import java.net.URL;
import java.util.Hashtable;
import java.util.ResourceBundle;
import java.util.Set;

import com.wiki.standalone.moxkiriya.SettingManager;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.ToggleGroup;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
import javafx.util.Callback;

/**
 * SelectPartyダイアログコントローラ
 */
public class SelectPartyDialogController extends DialogControllerBase {
	/**
	 * Party property.
	 */
	public class PartyProperty {
		/** Select status. */
		private SimpleBooleanProperty select_;

		/** Party name. */
		private SimpleStringProperty partyName_;
		
		/**
		 * Constructor.
		 * @param aSelect
		 * @param aPartyName
		 */
		public PartyProperty(boolean aSelect, String aPartyName) {
			select_    = new SimpleBooleanProperty(aSelect);
			partyName_ = new SimpleStringProperty(aPartyName);			
		}

		/**
		 * Select property getter.
		 * @return BooleanProperty
		 */
		public BooleanProperty selectProperty() {
			return select_;
		}

		/**
		 * Party name getter.
		 * @return StringProperty
		 */
		public StringProperty partyNameProperty() {
			return partyName_;
		}
	}
	
	@FXML   private TableView<PartyProperty>             tableViewPartyList;
	@FXML   private TableColumn<PartyProperty, Boolean>  tableColumnSelect;
	@FXML   private TableColumn<PartyProperty, String>   tableColumnPartyName;
	@FXML   private Button                               buttonCancel;
	@FXML	private Button                               buttonOK;
	@FXML	private Button                               buttonAddNewParty;

	/** Selected party name. */
	private String selectedParty_;

	/** ToggleGroup for select RadioButton. */
	private ToggleGroup toggleGroupSelect_;

	/** Close type. */
	private DialogBase.CloseType closeType_;

	/** My stage */
	private Stage          stage_;
	
	@Override
	public void initialize(URL url, ResourceBundle resource) {
		super.initialize(url, resource);

		buttonOK.setDisable(true);

		toggleGroupSelect_  = new ToggleGroup();

		setCellFactory(tableColumnSelect, toggleGroupSelect_, new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent event) {
				RadioButton   target        = (RadioButton)event.getTarget();
				PartyProperty partyProperty = (PartyProperty)target.getUserData();

				if(target.isSelected() == true) {
					buttonOK.setDisable(false);
					
					selectedParty_ = partyProperty.partyNameProperty().getValue();
				}
			}			
		});

		setCellFactory(tableColumnPartyName, new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent event) {
				Hyperlink     target        = (Hyperlink)event.getTarget();
				PartyProperty partyProperty = (PartyProperty)target.getUserData();
				String        partyName     = partyProperty.partyName_.get();
				
				try {
					if(showConfigSettingsDialog(stage_, partyName) == DialogBase.CloseType.OK) {
						SettingManager settingMgr = SettingManager.getInstance();
						String         path       = settingMgr.get(SettingManager.SETTINGSKEY_MOXKIRIYA_USER_DIR);
						settingMgr.loadSettingFiles(path);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}			
		});

		buildTableViewPartyList();

		SettingManager settingMgr   = SettingManager.getInstance();
		String         defaultParty = settingMgr.getSelectedParty();

		if(defaultParty != null) {
			buttonCancel.setDisable(false);
		}
	}

	/**
	 * Stage setter.
	 * @param stage
	 */
	public void setStage(Stage stage) {
		stage_ = stage;
	}

	/**
	 * 終了種別を取得する。
	 * @param closeType
	 */
	public DialogBase.CloseType getCloseType() {
		return closeType_;
	}

	@FXML
	public void onActionButtonCancel(ActionEvent event) {
		closeType_ = DialogBase.CloseType.Cancel;
		((Node)event.getSource()).getScene().getWindow().hide();
	}

	@FXML
	public void onActionButtonOK(ActionEvent event) {
		try {
			SettingManager                settingMgr     = SettingManager.getInstance();
			settingMgr.setSelectedParty(selectedParty_);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		closeType_ = DialogBase.CloseType.OK;
		((Node)event.getSource()).getScene().getWindow().hide();
	}

	@FXML
	public void onActionButtonAddNewParty(ActionEvent event) {
		try {
			showConfigSettingsDialog(stage_, null);

			SettingManager                settingMgr     = SettingManager.getInstance();
			Hashtable<String, Boolean>    partyTable     = settingMgr.getPartyTable();
			Set<String>                   keys           = partyTable.keySet();
			ObservableList<PartyProperty> observableList = FXCollections.observableArrayList();

			for(String key: keys) {
				boolean       isDefault     = partyTable.get(key);
				PartyProperty partyProperty = new PartyProperty(isDefault, key);
				observableList.add(partyProperty);
			}
			tableViewPartyList.getItems().clear();
			tableViewPartyList.setItems(observableList);		
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Cell factory setter.
	 * @param tableColumn
	 * @param toggleGroup
	 */
	private void setCellFactory(TableColumn<PartyProperty, Boolean> tableColumn, final ToggleGroup toggleGroup, final EventHandler<ActionEvent> eventHandler) {
		tableColumn.setCellFactory(new Callback<TableColumn<PartyProperty, Boolean>, TableCell<PartyProperty, Boolean>>() {
			@Override
			public TableCell<PartyProperty, Boolean> call(TableColumn<PartyProperty, Boolean> param) {
				TableCell<PartyProperty, Boolean> tableCell = new TableCell<PartyProperty, Boolean>() {
					@Override
					public void updateItem(Boolean select, boolean empty) {
						super.updateItem(select, empty);
						if(empty != true) {
							RadioButton radioButton = new RadioButton();

							radioButton.setOnAction(eventHandler);
							radioButton.setToggleGroup(toggleGroup);
							setGraphic(radioButton);

							int                           index = getIndex();
							ObservableList<PartyProperty> items = getTableView().getItems();
							radioButton.setUserData(items.get(index));
						}
					}
				};
				tableCell.setId("selectPartyRadioButtonTableCell");
				
				return tableCell;
			}
		});
	}
	
	/**
	 * Cell factory setter.
	 * @param tableColumn
	 */
	private void setCellFactory(TableColumn<PartyProperty, String> tableColumn, final EventHandler<ActionEvent> eventHandler) {
		tableColumn.setCellFactory(new Callback<TableColumn<PartyProperty, String>, TableCell<PartyProperty, String>>() {
			@Override
			public TableCell<PartyProperty, String> call(TableColumn<PartyProperty, String> param) {
				TableCell<PartyProperty, String> tableCell = new TableCell<PartyProperty, String>() {
					@Override
					public void updateItem(String partyName, boolean empty) {
						super.updateItem(partyName, empty);
						if(empty != true) {
							Hyperlink hyperlink = new Hyperlink(partyName);
							
							hyperlink.setOnAction(eventHandler);
							setGraphic(hyperlink);

							int                           index = getIndex();
							ObservableList<PartyProperty> items = getTableView().getItems();
							hyperlink.setUserData(items.get(index));
						}
					}
				};
				
				return tableCell;
			}
		});
	}

	/**
	 * Build party list TableView
	 */
	private void buildTableViewPartyList() {
		tableColumnSelect.setCellValueFactory(new PropertyValueFactory<PartyProperty, Boolean>("select"));
		tableColumnPartyName.setCellValueFactory(new PropertyValueFactory<PartyProperty, String>("partyName"));
		
		SettingManager                settingMgr     = SettingManager.getInstance();
		Hashtable<String, Boolean>    partyTable     = settingMgr.getPartyTable();
		Set<String>                   keys           = partyTable.keySet();
		ObservableList<PartyProperty> observableList = FXCollections.observableArrayList();

		for(String key: keys) {
			boolean       isDefault     = partyTable.get(key);
			PartyProperty partyProperty = new PartyProperty(isDefault, key);
			observableList.add(partyProperty);
		}
		tableViewPartyList.setItems(observableList);
	}

	/**
	 * WikiConfigSettingDialogを表示する。
	 * @param primaryStage
	 * @param selectedParty
	 * @return DialogBase.CloseType
	 * @throws Exception 
	 */
	private DialogBase.CloseType showConfigSettingsDialog(Stage stage, String partyName) throws Exception {
		SettingManager settingMgr_ = SettingManager.getInstance();
		
		ConfigSettingsDialog dialog = new ConfigSettingsDialog(partyName);
		
		DialogBase.CloseType closeType = dialog.showDialog(stage, resource_);
		if(closeType == DialogBase.CloseType.OK) {

			Hashtable<String, String> settingsTable = dialog.getSettingsTable();
			String                    path          = settingMgr_.get(SettingManager.SETTINGSKEY_MOXKIRIYA_USER_DIR);

			partyName = dialog.getPartyName();
			settingMgr_.putParty(partyName, dialog.getDefaultPartyCheckValue());
			settingMgr_.savePartyConfig(path);
			settingMgr_.saveSettingConfig(path, partyName, settingsTable);			
		}
		
		return closeType;
	}
}
