package com.concurrentperformance.ringingmaster.engine.notation.impl;

import com.concurrentperformance.ringingmaster.engine.NumberOfBells;
import com.concurrentperformance.ringingmaster.engine.notation.NotationCall;
import com.concurrentperformance.ringingmaster.engine.notation.NotationRow;

import java.util.List;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

/**
 * TODO
 * User: Stephen
 */
public class NotationCallBuilder {

	private String name;
	private String nameShorthand;
	private NumberOfBells numberOfWorkingBells = NumberOfBells.BELLS_8;
	private String notationShorthand;

	public NotationCall build() {
		checkState(name != null, "name must not be null");
		checkState(nameShorthand != null, "nameShorthand must not be null");
		checkState(notationShorthand != null, "notationShorthand must not be null");

		final List<NotationRow> notationElements = NotationBuilderHelper.getValidatedRowsFromShorthand(notationShorthand, numberOfWorkingBells);

		return new DefaultNotationCall(name,
										nameShorthand,
										numberOfWorkingBells,
										notationElements);
	}

	public NotationCallBuilder setName(final String name) {
		this.name = checkNotNull(name, "name must not be null");
		checkArgument(name.length() > 0, "name must not be empty");
		return this;
	}

	public NotationCallBuilder setNameShorthand(final String nameShorthand) {
		this.nameShorthand = checkNotNull(nameShorthand, "nameShorthand must not be null");
		checkArgument(nameShorthand.length() > 0, "name must not be empty");
		return this;
	}

	public NotationCallBuilder setNumberOfWorkingBells(final NumberOfBells numberOfWorkingBells) {
		this.numberOfWorkingBells = checkNotNull(numberOfWorkingBells, "numberOfWorkingBells must not be null");
		return this;
	}

	public NotationCallBuilder setUnfoldedNotationShorthand(final String notationShorthand) {
		this.notationShorthand = checkNotNull(notationShorthand, "notationShorthand must not be null");
		checkArgument(notationShorthand.length() > 0, "notationShorthand must not be empty");
		return this;
	}

	public void checkClashWith(NotationCallBuilder otherCallBuilder) {
		if (name.equals(otherCallBuilder.name)||
				name.equals(otherCallBuilder.nameShorthand) ||
				nameShorthand.equals(otherCallBuilder.name) ||
				nameShorthand.equals(otherCallBuilder.nameShorthand)) {
			throw new IllegalArgumentException("Name clash between Calls [" + toDisplayString() + "] and [" + otherCallBuilder.toDisplayString() + "]");
		}
		if (notationShorthand.equals(otherCallBuilder.notationShorthand)) {
			throw new IllegalArgumentException("Notation clash between Calls [" + toDisplayString() + "] and [" + otherCallBuilder.toDisplayString() + "]");
		}
	}

	public String toDisplayString() {
		return name + "(" + nameShorthand + ") :" + notationShorthand;

	}
		@Override
	public String toString() {
		return "NotationCallBuilder{" +
				"name='" + name + '\'' +
				", shorthand='" + nameShorthand + '\'' +
				", numberOfWorkingBells=" + numberOfWorkingBells +
				", notationShorthand='" + notationShorthand + '\'' +
				'}';
	}
}

@@ -2375,68 +2375,398 @@
 ame)
-%7C%7C%0D%0A%09%09%09%09name.equals(otherCallBuilder.nameShorthand) %7C%7C%0D%0A%09%09%09%09
+) %7B%0D%0A%09%09%09throw new IllegalArgumentException(%22Name of call %5B%22 + toDisplayString() + %22%5D clashes with name of call %5B%22 + otherCallBuilder.toDisplayString() + %22%5D%22);%0D%0A%09%09%7D%0D%0A%09%09if (name.equals(otherCallBuilder.nameShorthand)) %7B%0D%0A%09%09%09throw new IllegalArgumentException(%22Name of call %5B%22 + toDisplayString() + %22%5D clashes with shorthand of call %5B%22 + otherCallBuilder.toDisplayString() + %22%5D%22);%0D%0A%09%09%7D%0D%0A%09%09if (
 name
@@ -2808,17 +2808,184 @@
 ame)
- %7C%7C
+) %7B
 %0D%0A%09%09%09
-%09
+throw new IllegalArgumentException(%22Shorthand of call %5B%22 + toDisplayString() + %22%5D clashes with name of call %5B%22 + otherCallBuilder.toDisplayString() + %22%5D%22);%0D%0A%09%09%7D%0D%0A%09%09if (
 name
@@ -3080,32 +3080,25 @@
 on(%22
-Name clash between C
+Shorthand of c
 all
-s
  %5B%22 
@@ -3114,35 +3114,62 @@
 ayString() + %22%5D 
-and
+clashes with shorthand of call
  %5B%22 + otherCallB
@@ -3330,27 +3330,15 @@
 ion 
-clash between C
+of c
 all
-s
  %5B%22 
@@ -3362,19 +3362,45 @@
 () + %22%5D 
-and
+clashes with Notation of call
  %5B%22 + ot

improve logging ofc call clashes.