//   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.eventcore;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * <p>
 * This class is a dummy hierarchical event target to represent groups of event targets. A group of
 * event targets can be integrated in any hierarchical event target model using the method
 * {@link HierarchicalEventTargetModel#groupEventTargets(List, String, IEventTargetFactory)}. A
 * group has the same behavior as any other parent hierarchical event target.
 * </p>
 * 
 * @author Patrick Harms
 */
public class HierarchicalEventTargetGroup extends AbstractDefaultHierarchicalEventTarget {

    /**
     * <p>
     * default serial version UID
     * </p>
     */
    private static final long serialVersionUID = 1L;
    
    /**
     * the list of grouped event targets
     */
    private List<IHierarchicalEventTarget> groupedEventTargets =
        new LinkedList<IHierarchicalEventTarget>();

    /**
     * <p>
     * instantiates an event target group with a name and its optional parent event target
     * </p>
     *
     * @param groupName        the name of the event target group
     * @param parent           the optional parent event target of the group
     * @param eventTargetModel the event target model to which the group will belong
     */
    public HierarchicalEventTargetGroup(String                          groupName,
                                        IHierarchicalEventTarget        parent,
                                        HierarchicalEventTargetModel<?> eventTargetModel)
    {
        super(new GroupSpecification(groupName), parent);
        super.setEventTargetModel(eventTargetModel);
    }

    /* (non-Javadoc)
     * @see de.ugoe.cs.autoquest.eventcore.IEventTarget#getPlatform()
     */
    @Override
    public String getPlatform() {
        return "none";
    }

    /* (non-Javadoc)
     * @see de.ugoe.cs.autoquest.eventcore.IEventTarget#getStringIdentifier()
     */
    @Override
    public String getStringIdentifier() {
        return ((GroupSpecification) super.getSpecification()).name;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return getStringIdentifier();
    }

    /* (non-Javadoc)
     * @see IHierarchicalEventTarget#updateSpecification(IEventTargetSpec)
     */
    @Override
    public void updateSpecification(IEventTargetSpec furtherSpec) {
        // do nothing
    }

    /**
     * <p>
     * returns the list of event targets belonging to this group.
     * </p>
     * 
     * @return the event targets belonging to this group
     * 
     */
    public List<IHierarchicalEventTarget> getGroupedEventTargets() {
        return Collections.unmodifiableList(groupedEventTargets);
    }
    
    /**
     * <p>
     * allows adding a new event target to the group
     * </p>
     *
     * @param eventTarget the new member of the group
     */
    void addToGroup(IHierarchicalEventTarget eventTarget) {
        this.groupedEventTargets.add(eventTarget);
    }
    
    /**
     * <p>
     * internally required event target specification for an event target group. This is just a
     * wrapper for a name of an event target group
     * </p>
     * 
     * @author Patrick Harms
     */
    private static class GroupSpecification implements IEventTargetSpec {
        
        /**
         * <p>
         * default serial version UID
         * </p>
         */
        private static final long serialVersionUID = 1L;
        
        /**
         * <p>
         * the name of the event target group represented by this specification
         * </p>
         */
        private String name;

        /**
         * <p>
         * instantiates the group specification with the given name. Two group specifications
         * are only similar, if their names match.
         * </p>
         *
         * @param name the name of the group
         */
        private GroupSpecification(String name) {
            super();
            this.name = name;
        }

        /* (non-Javadoc)
         * @see IEventTargetSpec#getSimilarity(IEventTargetSpec)
         */
        @Override
        public boolean getSimilarity(IEventTargetSpec other) {
            return
                (other instanceof GroupSpecification) &&
                name.equals(((GroupSpecification) other).name);
        }

    }

}
