//   Copyright 2012 Georg-August-Universität Göttingen, Germany
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

package de.ugoe.cs.autoquest.usability.rules.patterns;

import de.ugoe.cs.autoquest.usability.rules.patterns.visitors.ContainsEventVisitor;
import de.ugoe.cs.autoquest.usability.rules.patterns.visitors.ContainsInteractionPatternVisitor;
import de.ugoe.cs.autoquest.usability.rules.patterns.visitors.EndsWithEventVisitor;
import de.ugoe.cs.autoquest.usability.rules.patterns.visitors.EndsWithInteractionPatternVisitor;
import de.ugoe.cs.autoquest.usability.rules.patterns.visitors.StartsWithEventVisitor;
import de.ugoe.cs.autoquest.usability.rules.patterns.visitors.StartsWithInteractionPatternVisitor;
import de.ugoe.cs.autoquest.usability.tasktree.filters.EventTypeFilter;
import de.ugoe.cs.autoquest.usability.tasktree.filters.TaskTypeFilter;

/**
 * <p>
 * TODO comment
 * </p>
 * 
 * @author Alexander Deicke
 */
public class InteractionPatternBuilder {

    protected TaskTypeFilter concernedNode;
    
    protected EventTypeFilter startsWithEvent;
    
    protected InteractionPattern startsWithPattern;
    
    protected EventTypeFilter endsWithEvent;
    
    protected InteractionPattern endsWithPattern;
    
    protected EventTypeFilter containsEvent;
    
    protected InteractionPattern containsPattern;
    
    /**
     * <p>
     * TODO: comment
     * </p>
     *
     * @param sequence
     * @return
     */
    public SpecifyPatternStep concernedNode(TaskTypeFilter concernedNode) {
        this.concernedNode = concernedNode;
        return new SpecifyPatternStep();
    }
    
    public class SpecifyPatternStep {

        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param textInput
         * @return
         */
        public BuildStartsWithEventStep startsWith(EventTypeFilter startsWithType) {
            InteractionPatternBuilder.this.startsWithEvent = startsWithType;
            return new BuildStartsWithEventStep();
        }
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param startsWithPattern
         * @return
         */
        public BuildStartsWithPatternStep startsWith(InteractionPattern startsWithPattern) {
            InteractionPatternBuilder.this.startsWithPattern = startsWithPattern;
            return new BuildStartsWithPatternStep();
        }
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param textInput
         * @return
         */
        public BuildEndsWithEventStep endsWith(EventTypeFilter endsWithType) {
            InteractionPatternBuilder.this.endsWithEvent = endsWithType;
            return new BuildEndsWithEventStep();
        }
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param endsWithPattern
         * @return
         */
        public BuildEndsWithPatternStep endsWith(InteractionPattern endsWithPattern) {
            InteractionPatternBuilder.this.endsWithPattern = endsWithPattern;
            return new BuildEndsWithPatternStep();
        }

        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param textInput
         * @return
         */
        public BuildContainsEventStep contains(EventTypeFilter containsType) {
            InteractionPatternBuilder.this.containsEvent = containsType;
            return new BuildContainsEventStep();
        }

        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param containsPattern
         * @return
         */
        public BuildContainsPatternStep contains(InteractionPattern containsPattern) {
            InteractionPatternBuilder.this.containsPattern = containsPattern;
            return new BuildContainsPatternStep();
        }
        
    }
    
    public class BuildStartsWithEventStep {

        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param endsWithType
         * @return
         */
        public BuildStartsAndEndsWithEventStep endsWith(EventTypeFilter endsWithType) {
            InteractionPatternBuilder.this.endsWithEvent = endsWithType;
            return new BuildStartsAndEndsWithEventStep();
        }
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param endsWithPattern
         * @return
         */
        public BuildStartsWithEventAndEndsWithPattern endsWith(InteractionPattern endsWithPattern) {
            InteractionPatternBuilder.this.endsWithPattern = endsWithPattern;
            return new BuildStartsWithEventAndEndsWithPattern();
        }
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param textInput
         * @return
         */
        public BuildStartsWithEventAndContainsEventStep contains(EventTypeFilter containsType) {
            InteractionPatternBuilder.this.containsEvent = containsType;
            return new BuildStartsWithEventAndContainsEventStep();
        }
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param containedPattern
         * @return
         */
        public BuildStartsWithEventAndContainsPatternStep contains(InteractionPattern containsPattern) {
            InteractionPatternBuilder.this.containsPattern = containsPattern;
            return new BuildStartsWithEventAndContainsPatternStep();
        }
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new StartsWithEventVisitor(startsWithEvent, concernedNode));
        }
        
    }
    
    public class BuildStartsWithPatternStep {

        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param containsEvent
         * @return
         */
        public BuildStartsWithPatternAndContainsEventStep contains(EventTypeFilter containsEvent) {
            InteractionPatternBuilder.this.containsEvent = containsEvent;
            return new BuildStartsWithPatternAndContainsEventStep();
        }
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param containedPattern
         * @return
         */
        public BuildStartsWithPatternAndContainsPatternStep contains(InteractionPattern containsPattern) {
            InteractionPatternBuilder.this.containsPattern = containsPattern;
            return new BuildStartsWithPatternAndContainsPatternStep();
        }
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param textInput
         * @return
         */
        public BuildStartsWithPatternAndEndsWithEventStep endsWith(EventTypeFilter endsWithEvent) {
            InteractionPatternBuilder.this.endsWithEvent = endsWithEvent;
            return new BuildStartsWithPatternAndEndsWithEventStep();
        }
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param endsWithPattern
         * @return
         */
        public BuildStartsAndEndsWithPatternStep endsWith(InteractionPattern endsWithPattern) {
            InteractionPatternBuilder.this.endsWithPattern = endsWithPattern;
            return new BuildStartsAndEndsWithPatternStep();
        }
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new StartsWithInteractionPatternVisitor(startsWithPattern, concernedNode));
        }
        
    }
    
    public class BuildEndsWithEventStep {

        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new EndsWithEventVisitor(endsWithEvent, concernedNode));
        }
        
    }
    
    public class BuildEndsWithPatternStep {

        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new EndsWithInteractionPatternVisitor(endsWithPattern, concernedNode));
        }
        
    }
    
    public class BuildContainsEventStep {

        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param textInput
         * @return
         */
        public BuildContainsAndEndsWithEventStep endsWith(EventTypeFilter endsWithType) {
            InteractionPatternBuilder.this.endsWithEvent = endsWithType;
            return new BuildContainsAndEndsWithEventStep();
        }
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new ContainsEventVisitor(containsEvent, concernedNode));
        }
        
    }
    
    public class BuildContainsPatternStep {
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new ContainsInteractionPatternVisitor(containsPattern, concernedNode));
        }
        
    }
    
    public class BuildStartsAndEndsWithEventStep {
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new StartsWithEventVisitor(startsWithEvent, concernedNode), new EndsWithEventVisitor(endsWithEvent, concernedNode));
        }
        
    }
    
    public class BuildStartsWithEventAndEndsWithPattern {
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new StartsWithEventVisitor(startsWithEvent, concernedNode), new EndsWithInteractionPatternVisitor(endsWithPattern, concernedNode));
        }
        
    }
    
    public class BuildStartsWithPatternAndEndsWithEventStep {
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new StartsWithInteractionPatternVisitor(startsWithPattern, concernedNode), new EndsWithEventVisitor(endsWithEvent, concernedNode));
        }
        
    }
    
    public class BuildStartsAndEndsWithPatternStep {
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new StartsWithInteractionPatternVisitor(startsWithPattern, concernedNode), new EndsWithInteractionPatternVisitor(endsWithPattern, concernedNode));
        }
        
    }
    
    public class BuildStartsWithEventAndContainsEventStep {
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param textInput
         * @return
         */
        public BuildStartsAndEndsWithEventAndContainsEventStep endsWith(EventTypeFilter endsWithEvent) {
            InteractionPatternBuilder.this.endsWithEvent = endsWithEvent;
            return new BuildStartsAndEndsWithEventAndContainsEventStep();
        }
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param endsWithPattern
         * @return
         */
        public BuildStartsWithEventContainsEventAndEndsWithPatternStep endsWith(InteractionPattern endsWithPattern) {
            InteractionPatternBuilder.this.endsWithPattern = endsWithPattern;
            return new BuildStartsWithEventContainsEventAndEndsWithPatternStep();
        }
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new StartsWithEventVisitor(startsWithEvent, concernedNode), new ContainsEventVisitor(containsEvent, concernedNode));
        }
        
    }
    
    public class BuildStartsWithPatternAndContainsPatternStep {
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param textInput
         * @return
         */
        public BuildStartsContainsPatternAndEndsWithEventStep endsWith(EventTypeFilter endsWithEvent) {
            InteractionPatternBuilder.this.endsWithEvent = endsWithEvent;
            return new BuildStartsContainsPatternAndEndsWithEventStep();
        }
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param endsWithPattern
         * @return
         */
        public BuildStartsAndEndsWithPatternAndContainsPatternStep endsWith(InteractionPattern endsWithPattern) {
            InteractionPatternBuilder.this.endsWithPattern = endsWithPattern;
            return new BuildStartsAndEndsWithPatternAndContainsPatternStep();
        }
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new StartsWithInteractionPatternVisitor(startsWithPattern, concernedNode), new ContainsInteractionPatternVisitor(containsPattern, concernedNode));
        }
        
    }
    
    public class BuildStartsWithEventAndContainsPatternStep {
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param textInput
         * @return
         */
        public BuildStartsWithEventContainsPatternAndEndsWithEventStep endsWith(EventTypeFilter endsWithEvent) {
            InteractionPatternBuilder.this.endsWithEvent = endsWithEvent;
            return new BuildStartsWithEventContainsPatternAndEndsWithEventStep();
        }
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param endsWithPattern
         * @return
         */
        public BuildStartsWithEventContainsPatternAndEndsWithPatternStep endsWith(InteractionPattern endsWithPattern) {
            InteractionPatternBuilder.this.endsWithPattern = endsWithPattern;
            return new BuildStartsWithEventContainsPatternAndEndsWithPatternStep();
        }
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new StartsWithEventVisitor(startsWithEvent, concernedNode), new ContainsInteractionPatternVisitor(containsPattern, concernedNode));
        }
        
    }
    
    public class BuildStartsWithPatternAndContainsEventStep {
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param textInput
         * @return
         */
        public BuildStartsWithPatternContainsEventAndEndsWithEventStep endsWith(EventTypeFilter endsWithEvent) {
            InteractionPatternBuilder.this.endsWithEvent = endsWithEvent;
            return new BuildStartsWithPatternContainsEventAndEndsWithEventStep();
        }
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @param endsWithPattern
         * @return
         */
        public BuildStartsWithPatternContainsEventAndEndsWithPatternStep endsWith(InteractionPattern endsWithPattern) {
            InteractionPatternBuilder.this.endsWithPattern = endsWithPattern;
            return new BuildStartsWithPatternContainsEventAndEndsWithPatternStep();
        }
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new StartsWithInteractionPatternVisitor(startsWithPattern, concernedNode), new ContainsEventVisitor(containsEvent, concernedNode));
        }
        
    }
    
    public class BuildStartsAndEndsWithEventAndContainsEventStep {
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new StartsWithEventVisitor(startsWithEvent, concernedNode), new EndsWithEventVisitor(endsWithEvent, concernedNode), new ContainsEventVisitor(containsEvent, concernedNode));
        }
        
    }
    
    public class BuildStartsContainsPatternAndEndsWithEventStep {
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new StartsWithInteractionPatternVisitor(startsWithPattern, concernedNode), new ContainsInteractionPatternVisitor(containsPattern, concernedNode), new EndsWithEventVisitor(endsWithEvent, concernedNode));
        }
        
    }
    
    public class BuildStartsAndEndsWithPatternAndContainsPatternStep {
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new StartsWithInteractionPatternVisitor(startsWithPattern, concernedNode), new EndsWithInteractionPatternVisitor(endsWithPattern, concernedNode), new ContainsInteractionPatternVisitor(containsPattern, concernedNode));
        }
        
    }
    
    public class BuildStartsWithEventContainsEventAndEndsWithPatternStep {
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new StartsWithEventVisitor(startsWithEvent, concernedNode), new ContainsEventVisitor(containsEvent, concernedNode), new EndsWithInteractionPatternVisitor(endsWithPattern, concernedNode));
        }
        
    }
    
    public class BuildStartsWithEventContainsPatternAndEndsWithEventStep {
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new StartsWithEventVisitor(startsWithEvent, concernedNode), new ContainsInteractionPatternVisitor(containsPattern, concernedNode), new EndsWithEventVisitor(endsWithEvent, concernedNode));
        }
        
    }
    
    public class BuildStartsWithEventContainsPatternAndEndsWithPatternStep {
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new StartsWithEventVisitor(startsWithEvent, concernedNode), new ContainsInteractionPatternVisitor(containsPattern, concernedNode), new EndsWithInteractionPatternVisitor(endsWithPattern, concernedNode));
        }
        
    }
    
    public class BuildStartsWithPatternContainsEventAndEndsWithEventStep {
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new StartsWithInteractionPatternVisitor(startsWithPattern, concernedNode), new ContainsEventVisitor(containsEvent, concernedNode), new EndsWithEventVisitor(endsWithEvent, concernedNode));
        }
        
    }
    
    public class BuildStartsWithPatternContainsEventAndEndsWithPatternStep {
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new StartsWithInteractionPatternVisitor(startsWithPattern, concernedNode), new ContainsEventVisitor(containsEvent, concernedNode), new EndsWithInteractionPatternVisitor(endsWithPattern, concernedNode));
        }
        
    }
    
    public class BuildContainsAndEndsWithEventStep {
        
        /**
         * <p>
         * TODO: comment
         * </p>
         *
         * @return
         */
        public InteractionPattern build() {
            return new InteractionPattern(concernedNode, new ContainsEventVisitor(containsEvent, concernedNode), new EndsWithEventVisitor(endsWithEvent, concernedNode));
        }
        
    }

}
