//   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.ContainsPatternVisitor;
import de.ugoe.cs.autoquest.usability.rules.patterns.visitors.EndsWithEventVisitor;
import de.ugoe.cs.autoquest.usability.rules.patterns.visitors.EndsWithPatternVisitor;
import de.ugoe.cs.autoquest.usability.rules.patterns.visitors.StartsWithEventVisitor;
import de.ugoe.cs.autoquest.usability.rules.patterns.visitors.StartsWithPatternVisitor;
import de.ugoe.cs.autoquest.usability.tasktree.filters.EventTypeFilter;
import de.ugoe.cs.autoquest.usability.tasktree.filters.TaskTreeNodeTypeFilter;

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

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

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

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

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

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

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

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

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

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

}
