package org.dbgl.gui.controls;

import java.util.List;
import java.util.OptionalInt;
import java.util.stream.IntStream;
import org.apache.commons.lang3.StringUtils;
import org.dbgl.model.entity.ITitledEntity;
import org.dbgl.service.SettingsService;
import org.dbgl.service.TextService;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;


public final class Combo_ {

	public static final String DYN_OPT_SECTION = "dynOptSection";
	public static final String DYN_OPT_ITEM = "dynOptItem";

	private final Combo combo_;

	private Combo_(Builder builder) {
		combo_ = new Combo(builder.composite_, builder.style_);
		if (DarkTheme.forced()) {
			combo_.setBackground(DarkTheme.inputBackground);
			combo_.setForeground(DarkTheme.defaultForeground);
		}
		combo_.setLayoutData(builder.layoutData());
		combo_.setVisibleItemCount(builder.visibleItemCount_);

		if (builder.tooltip_ != null)
			combo_.setToolTipText(builder.tooltip_);
		if (builder.items_ != null)
			combo_.setItems(builder.items_);
		if (builder.select_ >= 0)
			combo_.select(builder.select_);

		if (StringUtils.isNoneBlank(builder.dynOptSection_, builder.dynOptItem_)) {
			combo_.setData(DYN_OPT_SECTION, builder.dynOptSection_);
			combo_.setData(DYN_OPT_ITEM, builder.dynOptItem_);
		}

		if (builder.autoSelect_) {
			combo_.setData("currentLength", 0);
			combo_.setData("mutex", false);
			combo_.addModifyListener(event -> {
				if (!(boolean)combo_.getData("mutex")) {
					String text = combo_.getText();
					int newLength = text.length();
					if (newLength > (int)combo_.getData("currentLength")) {
						OptionalInt opt = IntStream.range(0, combo_.getItemCount()).filter(i -> combo_.getItem(i).toLowerCase().startsWith(text.toLowerCase())).findFirst();
						if (opt.isPresent()) {
							combo_.setData("mutex", true);
							combo_.setText(text + combo_.getItem(opt.getAsInt()).substring(newLength));
							combo_.setSelection(new Point(newLength, combo_.getText().length()));
							combo_.setData("mutex", false);
						}
					}
					combo_.setData("currentLength", newLength);
				}
			});
		}
	}

	public Combo ctrl() {
		return combo_;
	}

	public static Builder on(Composite composite) {
		return new Builder(composite);
	}

	public static final class Builder extends ControlBuilder<Builder> {
		int visibleItemCount_ = 10;
		String tooltip_;
		String[] items_;
		int select_ = -1;
		boolean autoSelect_ = false;
		String dynOptSection_, dynOptItem_;

		Builder(Composite composite) {
			super(composite, SWT.READ_ONLY, SWT.BEGINNING, SWT.CENTER, false, false);
		}

		public Builder tooltip(String key) {
			tooltip_ = TextService.getInstance().get(key);
			return this;
		}

		public Builder editable() {
			return style(SWT.NONE);
		}

		public Builder wide() {
			horizontalAlignment_ = SWT.FILL;
			grabExcessHorizontalSpace_ = true;
			return this;
		}

		public Builder autoSelect(List<ITitledEntity> values) {
			autoSelect_ = true;
			items(values.stream().map(ITitledEntity::getTitle).toArray(String[]::new));
			wide();
			editable();
			visibleItemCount(15);
			return this;
		}

		public Builder visibleItemCount(int count) {
			visibleItemCount_ = count;
			return this;
		}

		public Builder items(String[] items) {
			items_ = items;
			return this;
		}

		public Builder items(List<String> items) {
			items_ = items.toArray(new String[items.size()]);
			return this;
		}

		public Builder items(String section, String item) {
			items_ = SettingsService.getInstance().getValues(section, item);
			dynOptSection_ = section;
			dynOptItem_ = item;
			return this;
		}

		public Builder select(int select) {
			select_ = select;
			return this;
		}

		public Combo_ build() {
			return new Combo_(this);
		}

		public Combo ctrl() {
			return build().ctrl();
		}
	}
}
