//   Copyright 2015 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.guimodel;

import de.ugoe.cs.autoquest.eventcore.HierarchicalEventTargetGroup;
import de.ugoe.cs.autoquest.eventcore.IEventTargetSpec;

/**
 * <p>
 * implementation of event target groups for GUI elements
 * </p>
 * 
 * @author Patrick Harms
 */
public class GUIElementGroup extends HierarchicalEventTargetGroup implements IGUIElement {

    /**  */
    private static final long serialVersionUID = 1L;
    
    /** the internal fake event target specification */
    private GroupSpecification groupSpecification;
    
    /** stores if the usage of the group was observed (just to match the implemented interface */
    private boolean usageObserved = false;

    /**
     * <p>
     * instantiates a GUI element group with a name and its optional parent GUI element
     * </p>
     *
     * @param groupName        the name of the GUI element group
     * @param parent           the optional parent GUI element of the group
     * @param eventTargetModel the GUI model to which the group will belong
     */
    public GUIElementGroup(String      groupName,
                           IGUIElement parent,
                           GUIModel    guiModel)
    {
        super(groupName, parent, guiModel);
        groupSpecification = new GroupSpecification(groupName);
    }

    /* (non-Javadoc)
     * @see de.ugoe.cs.autoquest.eventcore.AbstractDefaultHierarchicalEventTarget#getSpecification()
     */
    @Override
    public IGUIElementSpec getSpecification() {
        return groupSpecification;
    }

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

    /* (non-Javadoc)
     * @see de.ugoe.cs.autoquest.eventcore.AbstractDefaultHierarchicalEventTarget#getParent()
     */
    @Override
    public IGUIElement getParent() {
        return (IGUIElement) super.getParent();
    }

    /* (non-Javadoc)
     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#getView()
     */
    @Override
    public IGUIView getView() {
        return null;
    }

    /* (non-Javadoc)
     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#getGUIModel()
     */
    @Override
    public GUIModel getGUIModel() {
        return (GUIModel) super.getEventTargetModel();
    }

    /* (non-Javadoc)
     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#isUsed()
     */
    @Override
    public boolean isUsed() {
        return usageObserved;
    }

    /* (non-Javadoc)
     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#markUsed()
     */
    @Override
    public void markUsed() {
        usageObserved = true;
    }

    /* (non-Javadoc)
     * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#getDistanceTo(IGUIElement)
     */
    @Override
    public double getDistanceTo(IGUIElement otherElement) {
        if (equals(otherElement)) {
            return 0.0;
        }
        else if (getParent() != null) {
            return getParent().getDistanceTo(otherElement);
        }
        else {
            return 1.0;
        }
    }
    
    /**
     * <p>
     * internally required GUI element specification for a GUI element group. This is just a wrapper
     * for a name of a GUI element group
     * </p>
     * 
     * @author Patrick Harms
     */
    private static class GroupSpecification implements IGUIElementSpec {
        
        /**
         * <p>
         * default serial version UID
         * </p>
         */
        private static final long serialVersionUID = 1L;
        
        /**
         * <p>
         * the name of the GUI element 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 de.ugoe.cs.autoquest.eventcore.IEventTargetSpec#getSimilarity(IEventTargetSpec)
         */
        @Override
        public boolean getSimilarity(IEventTargetSpec other) {
            return
                (other instanceof GroupSpecification) &&
                name.equals(((GroupSpecification) other).name);
        }

        /* (non-Javadoc)
         * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementSpec#getType()
         */
        @Override
        public String getType() {
            return "GUI element group";
        }

        /* (non-Javadoc)
         * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementSpec#getTypeHierarchy()
         */
        @Override
        public String[] getTypeHierarchy() {
            return new String[] { getType() };
        }

    }
}
