package org.dbgl.gui.controls;

import java.util.List;
import java.util.OptionalInt;
import java.util.stream.IntStream;

import org.dbgl.model.entity.ITitledEntity;
import org.dbgl.service.TextService;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;


public final class Combo_ {

	private final Combo combo_;

	private Combo_(Builder builder) {
		combo_ = new Combo(builder.composite_, builder.style_);
		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 (builder.autoSelect_) {
			combo_.setData("currentLength", 0);
			combo_.setData("mutex", false);
			combo_.addModifyListener(new ModifyListener() {
				public void modifyText(ModifyEvent 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;

		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(x -> x.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 select(int select) {
			select_ = select;
			return this;
		}

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

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