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

import static org.junit.Assert.*;

import org.junit.Test;

import de.ugoe.cs.autoquest.eventcore.guimodel.AbstractDefaultGUIElement;
import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement;
import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementSpec;

/**
 *
 */
public class AbstractDefaultGUIElementTest {

    /**
     *
     */
    @Test
    public void testRegisteringEqualGuiElements() {
        IGUIElement guiElement1 = new AbstractDefaultGUIElementTestImpl();
        IGUIElement guiElement2 = new AbstractDefaultGUIElementTestImpl();
        
        assertCompletelyUnequal(guiElement1, guiElement2);
        
        guiElement1.addEqualGUIElement(guiElement2);
        assertCompletelyEqual(guiElement1, guiElement2);
        
        IGUIElement guiElement3 = new AbstractDefaultGUIElementTestImpl();
        
        assertCompletelyEqual(guiElement1, guiElement2);
        assertCompletelyUnequal(guiElement1, guiElement3);
        assertCompletelyUnequal(guiElement2, guiElement3);
        
        guiElement1.addEqualGUIElement(guiElement3);
        assertCompletelyEqual(guiElement1, guiElement2, guiElement3);

        IGUIElement guiElement4 = new AbstractDefaultGUIElementTestImpl();
        
        assertCompletelyEqual(guiElement1, guiElement2, guiElement3);
        assertCompletelyUnequal(guiElement1, guiElement4);
        assertCompletelyUnequal(guiElement2, guiElement4);
        assertCompletelyUnequal(guiElement3, guiElement4);
        
        guiElement3.addEqualGUIElement(guiElement4);
        assertCompletelyEqual(guiElement1, guiElement2, guiElement3, guiElement4);
    }
    
    /**
     *
     */
    private void assertCompletelyUnequal(IGUIElement... guiElements) {
        for (int i = 0; i < guiElements.length; i++) {
            for (int j = i + 1; j < guiElements.length; j++) {
                assertFalse(guiElements[i].equals(guiElements[j]));
                assertFalse(guiElements[j].equals(guiElements[i]));
            }
        }
    }

    /**
     *
     */
    private void assertCompletelyEqual(IGUIElement... guiElements) {
        for (int i = 0; i < guiElements.length; i++) {
            for (int j = i; j < guiElements.length; j++) {
                assertTrue(guiElements[i].equals(guiElements[j]));
                assertTrue(guiElements[j].equals(guiElements[i]));
                assertEquals(guiElements[i].hashCode(), guiElements[j].hashCode());
            }
        }
    }

    /**
     *
     */
    public class AbstractDefaultGUIElementTestImpl extends AbstractDefaultGUIElement
        implements IGUIElement
    {

        /**
         *
         */
        public AbstractDefaultGUIElementTestImpl() {
            super(null, null);
        }

        /**  */
        private static final long serialVersionUID = 1L;

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

        /* (non-Javadoc)
         * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#updateSpecification(IGUIElementSpec)
         */
        @Override
        public void updateSpecification(IGUIElementSpec furtherSpec) {
            throw new UnsupportedOperationException();
        }

        @Override
        public String getStringIdentifier() {
            return "DUMMY";
        }

        /* (non-Javadoc)
         * @see de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElement#getDistanceTo(IGUIElement)
         */
        @Override
        public double getDistanceTo(IGUIElement otherElement) {
            if (this == otherElement) {
                return 0.0;
            }
            else {
                return 1.0;
            }
        }

    }

}
