package logbook.gui;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import logbook.config.ShipGroupConfig;
import logbook.config.bean.ShipGroupBean;
import logbook.config.bean.ShipGroupListBean;
import logbook.constants.AppConstants;
import logbook.data.context.GlobalContext;
import logbook.dto.ShipDto;
import logbook.gui.logic.CreateReportLogic;
import logbook.gui.logic.TableItemCreator;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.wb.swt.SWTResourceManager;
/**
* グループエディター
*
*/
public final class ShipFilterGroupDialog extends AbstractTableDialog {
private Text text;
private SashForm sashForm;
private Composite sideComposite;
private Composite mainComposite;
private Combo shipcombo;
private Tree tree;
private TreeItem treeItem;
private Button btnAddShip;
private Button btnRemoveShip;
private final Map<String, ShipDto> shipmap = new HashMap<String, ShipDto>();
/** 現在表示しているグループ */
private GroupProperty property;
/**
* Create the dialog.
* @param parent
* @param style
*/
public ShipFilterGroupDialog(Shell parent) {
super(parent);
}
/**
* Create contents of the dialog.
*/
@Override
protected void createContentsBefore() {
GridLayout shellLayout = new GridLayout(1, false);
shellLayout.verticalSpacing = 1;
shellLayout.marginWidth = 1;
shellLayout.marginHeight = 1;
shellLayout.marginBottom = 1;
shellLayout.horizontalSpacing = 1;
this.shell.setLayout(shellLayout);
this.sashForm = new SashForm(this.shell, SWT.SMOOTH);
this.sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
this.sideComposite = new Composite(this.sashForm, SWT.NONE);
GridLayout sideLayout = new GridLayout(2, false);
sideLayout.verticalSpacing = 1;
sideLayout.marginWidth = 1;
sideLayout.marginHeight = 1;
sideLayout.marginBottom = 1;
sideLayout.horizontalSpacing = 1;
this.sideComposite.setLayout(sideLayout);
Button btnAdd = new Button(this.sideComposite, SWT.NONE);
btnAdd.addSelectionListener(new AddGroupAdapter(this));
btnAdd.setImage(SWTResourceManager.getImage(ShipFilterGroupDialog.class, AppConstants.R_ICON_ADD));
Button btnRemove = new Button(this.sideComposite, SWT.NONE);
btnRemove.addSelectionListener(new RemoveGroupAdapter(this));
btnRemove.setImage(SWTResourceManager.getImage(ShipFilterGroupDialog.class, AppConstants.R_ICON_DELETE));
this.tree = new Tree(this.sideComposite, SWT.BORDER);
this.tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
this.tree.addSelectionListener(new TreeSelectionAdapter(this));
this.treeItem = new TreeItem(this.tree, SWT.NONE);
this.treeItem.setImage(SWTResourceManager.getImage(ShipFilterGroupDialog.class, AppConstants.R_ICON_STAR));
this.treeItem.setText("Group");
ShipGroupListBean shipGroupList = ShipGroupConfig.get();
for (ShipGroupBean bean : shipGroupList.getGroup()) {
TreeItem groupItem = new TreeItem(this.treeItem, SWT.NONE);
groupItem.setImage(SWTResourceManager
.getImage(ShipFilterGroupDialog.class, AppConstants.R_ICON_FOLDER));
groupItem.setText(bean.getName());
groupItem.setData(new GroupProperty(bean, groupItem));
}
this.treeItem.setExpanded(true);
this.mainComposite = new Composite(this.sashForm, SWT.NONE);
GridLayout mainLayout = new GridLayout(3, false);
mainLayout.verticalSpacing = 1;
mainLayout.marginWidth = 1;
mainLayout.marginHeight = 1;
mainLayout.marginBottom = 1;
mainLayout.horizontalSpacing = 1;
this.mainComposite.setLayout(mainLayout);
this.text = new Text(this.mainComposite, SWT.BORDER);
this.text.addModifyListener(new ModifyNameAdapter(this));
this.text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1));
this.text.setEnabled(false);
}
/**
* Create contents of the dialog.
*/
@Override
protected void createContents() {
this.table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1));
this.shipcombo = new Combo(this.mainComposite, SWT.READ_ONLY);
this.setShipComboData();
this.shipcombo.setEnabled(false);
this.btnAddShip = new Button(this.mainComposite, SWT.NONE);
this.btnAddShip.setText("Add");
this.btnAddShip.addSelectionListener(new AddShipAdapter(this));
this.btnAddShip.setEnabled(false);
this.btnRemoveShip = new Button(this.mainComposite, SWT.NONE);
this.btnRemoveShip.setText("Remove");
this.btnRemoveShip.addSelectionListener(new RemoveShipAdapter(this));
this.btnRemoveShip.setEnabled(false);
this.sashForm.setWeights(new int[] { 2, 5 });
}
@Override
protected Composite getTableParent() {
return this.mainComposite;
}
@Override
protected String getTitle() {
return "Group Editor";
}
@Override
protected Point getSize() {
return new Point(600, 350);
}
@Override
protected String[] getTableHeader() {
return new String[] { "", "ID", "Fleet", "Name", "Type", "Lv", "Morale" };
}
@Override
protected void updateTableBody() {
List<String[]> body = new ArrayList<String[]>();
if (this.property != null) {
List<ShipDto> shipList = this.property.getShipList();
for (int i = 0; i < shipList.size(); i++) {
ShipDto ship = shipList.get(i);
body.add(new String[] {
Integer.toString(i + 1),
Long.toString(ship.getId()),
ship.getFleetid(),
ship.getName(),
ship.getType(),
Long.toString(ship.getLv()),
Long.toString(ship.getCond())
});
}
}
this.body = body;
}
@Override
protected TableItemCreator getTableItemCreator() {
return CreateReportLogic.DEFAULT_TABLE_ITEM_CREATOR;
}
@Override
protected SelectionListener getHeaderSelectionListener() {
return new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (e.getSource() instanceof TableColumn) {
ShipFilterGroupDialog.this.sortTableItems((TableColumn) e.getSource());
}
}
};
}
@Override
protected void reloadTable() {
super.reloadTable();
// 名前・ボタンの状態をセットします
if (this.property != null) {
ShipGroupBean group = this.property.getShipGroupBean();
this.text.setText(group.getName());
this.text.setEnabled(true);
this.shipcombo.setEnabled(true);
this.btnAddShip.setEnabled(true);
this.btnRemoveShip.setEnabled(true);
} else {
this.text.setText("");
this.text.setEnabled(false);
this.shipcombo.setEnabled(false);
this.btnAddShip.setEnabled(false);
this.btnRemoveShip.setEnabled(false);
}
}
/**
* コンボボックスに艦娘をセットします
*
* @param combo
*/
private void setShipComboData() {
// コンボボックスから全ての艦娘を削除
this.shipcombo.removeAll();
// 表示用文字列と艦娘の紐付けを削除
this.shipmap.clear();
// 艦娘IDの最大を取得してゼロ埋め長さを算出
long maxshipid = 0;
for (ShipDto ship : GlobalContext.getShipMap().values()) {
maxshipid = Math.max(ship.getId(), maxshipid);
}
int padlength = Long.toString(maxshipid).length();
// 表示用文字列と艦娘の紐付けを追加
for (ShipDto ship : GlobalContext.getShipMap().values()) {
this.shipmap.put(this.getShipLabel(ship, padlength), ship);
}
// 艦娘を経験値順でソート
List<ShipDto> ships = new ArrayList<ShipDto>(this.shipmap.values());
Collections.sort(ships, new Comparator<ShipDto>() {
@Override
public int compare(ShipDto o1, ShipDto o2) {
return Long.compare(o2.getExp(), o1.getExp());
}
});
// コンボボックスに追加
for (int i = 0; i < ships.size(); i++) {
String key = this.getShipLabel(ships.get(i), padlength);
this.shipcombo.add(key);
}
// コントロールを再配置
this.shipcombo.pack();
this.shipcombo.getParent().pack();
}
/**
* 艦娘のプルダウン表示用文字列を作成します
*
* @param ship
* @param padlength
* @return
*/
private String getShipLabel(ShipDto ship, int padlength) {
return new StringBuilder().append(StringUtils.leftPad(Long.toString(ship.getId()), padlength, '0'))
.append(": ").append(ship.getName()).append(" (Lv").append(ship.getLv() + ")").toString();
}
/**
* グループを追加するときに呼び出されるアダプター
*
*/
private static final class AddGroupAdapter extends SelectionAdapter {
/** ダイアログ */
private final ShipFilterGroupDialog dialog;
/**
* コンストラクター
*/
public AddGroupAdapter(ShipFilterGroupDialog dialog) {
this.dialog = dialog;
}
@Override
public void widgetSelected(SelectionEvent e) {
List<ShipGroupBean> shipGroupList = ShipGroupConfig.get().getGroup();
ShipGroupBean bean = new ShipGroupBean();
bean.setName("New Group");
shipGroupList.add(bean);
TreeItem item = new TreeItem(this.dialog.treeItem, SWT.NONE);
item.setImage(SWTResourceManager.getImage(ShipFilterGroupDialog.class, AppConstants.R_ICON_FOLDER));
item.setText(bean.getName());
item.setData(new GroupProperty(bean, item));
this.dialog.treeItem.setExpanded(true);
}
}
/**
* グループを除去するときに呼び出されるアダプター
*
*/
private static final class RemoveGroupAdapter extends SelectionAdapter {
/** ダイアログ */
private final ShipFilterGroupDialog dialog;
/**
* コンストラクター
*/
public RemoveGroupAdapter(ShipFilterGroupDialog dialog) {
this.dialog = dialog;
}
@Override
public void widgetSelected(SelectionEvent e) {
if (this.dialog.property != null) {
ShipGroupBean target = this.dialog.property.getShipGroupBean();
MessageBox box = new MessageBox(this.dialog.shell, SWT.YES | SWT.NO
| SWT.ICON_QUESTION);
box.setText("Confirmation");
box.setMessage("Do you want to remove " + target.getName() + "from the group list?");
if (box.open() == SWT.YES) {
List<ShipGroupBean> shipGroupList = ShipGroupConfig.get().getGroup();
for (int i = 0; i < shipGroupList.size(); i++) {
if (shipGroupList.get(i) == target) {
shipGroupList.remove(i);
}
}
this.dialog.text.setText("");
this.dialog.property.getTreeItem().dispose();
this.dialog.property = null;
}
}
}
}
/**
* 名前を変更した時に呼び出されるアダプター
*
*/
private static final class ModifyNameAdapter implements ModifyListener {
/** ダイアログ */
private final ShipFilterGroupDialog dialog;
/**
* コンストラクター
*/
public ModifyNameAdapter(ShipFilterGroupDialog dialog) {
this.dialog = dialog;
}
@Override
public void modifyText(ModifyEvent e) {
if (this.dialog.property != null) {
String text = this.dialog.text.getText();
this.dialog.property.getTreeItem().setText(text);
ShipGroupBean group = this.dialog.property.getShipGroupBean();
group.setName(text);
}
}
}
/**
* ツリーをクリックした時に呼び出されるアダプター
*
*/
private static final class TreeSelectionAdapter extends SelectionAdapter {
/** ダイアログ */
private final ShipFilterGroupDialog dialog;
/**
* コンストラクター
*/
public TreeSelectionAdapter(ShipFilterGroupDialog dialog) {
this.dialog = dialog;
}
@Override
public void widgetSelected(SelectionEvent e) {
if (e.item != null) {
Object data = e.item.getData();
if (data instanceof GroupProperty) {
this.dialog.property = (GroupProperty) data;
} else {
this.dialog.property = null;
}
this.dialog.reloadTable();
}
}
}
/**
* 艦娘を追加するときに呼び出されるアダプター
*
*/
private static final class AddShipAdapter extends SelectionAdapter {
/** ダイアログ */
private final ShipFilterGroupDialog dialog;
/**
* コンストラクター
*/
public AddShipAdapter(ShipFilterGroupDialog dialog) {
this.dialog = dialog;
}
@Override
public void widgetSelected(SelectionEvent e) {
if (this.dialog.property != null) {
if (this.dialog.shipcombo.getSelectionIndex() >= 0) {
ShipGroupBean target = this.dialog.property.getShipGroupBean();
ShipDto ship = this.dialog.shipmap.get(this.dialog.shipcombo.getItem(this.dialog.shipcombo
.getSelectionIndex()));
target.getShips().add(ship.getId());
this.dialog.reloadTable();
}
}
}
}
/**
* 艦娘を除去するときに呼び出されるアダプター
*
*/
private static final class RemoveShipAdapter extends SelectionAdapter {
/** ダイアログ */
private final ShipFilterGroupDialog dialog;
/**
* コンストラクター
*/
public RemoveShipAdapter(ShipFilterGroupDialog dialog) {
this.dialog = dialog;
}
@Override
public void widgetSelected(SelectionEvent e) {
if (this.dialog.property != null) {
ShipGroupBean target = this.dialog.property.getShipGroupBean();
TableItem[] items = this.dialog.table.getSelection();
for (TableItem tableItem : items) {
String text = tableItem.getText(1);
if (StringUtils.isNumeric(text)) {
Long id = Long.valueOf(text);
target.getShips().remove(id);
}
}
this.dialog.reloadTable();
}
}
}
/**
* テーブルに表示する所有艦娘のグループ
*
*/
private static final class GroupProperty {
/** 所有艦娘のグループ */
private final ShipGroupBean shipGroup;
/** TreeItem */
private final TreeItem item;
/**
* コンストラクター
*
* @param shipGroup 所有艦娘のグループ
* @param item TreeItem
*/
public GroupProperty(ShipGroupBean shipGroup, TreeItem item) {
this.shipGroup = shipGroup;
this.item = item;
}
/**
* 所有艦娘のグループを取得します
*
* @return 所有艦娘のグループ
*/
public ShipGroupBean getShipGroupBean() {
return this.shipGroup;
}
/**
* TreeItemを取得します
* @return TreeItem
*/
public TreeItem getTreeItem() {
return this.item;
}
/**
* 艦娘のリストを取得します
*
* @return 艦娘のリスト
*/
public List<ShipDto> getShipList() {
List<ShipDto> ships = new ArrayList<ShipDto>();
Map<Long, ShipDto> shipMap = GlobalContext.getShipMap();
for (Long id : this.shipGroup.getShips()) {
ShipDto ship = shipMap.get(id);
if (ship != null) {
ships.add(ship);
}
}
return ships;
}
}
}