package com.project.shared.client.utils; import java.util.ArrayList; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; import com.google.gwt.dom.client.Element; import com.project.shared.utils.MapUtils; //TODO: Think about a better design. public abstract class ZIndexAllocator { private static int _nextZIndex = 1; private static TreeMap<Integer, Element> _zIndexMap = new TreeMap<Integer, Element>(); public static void reset() { _nextZIndex = 1; _zIndexMap.clear(); } public static int allocateSetZIndex(Element element) { int allocatedZIndex = _nextZIndex; _nextZIndex += 1; element.getStyle().setZIndex(allocatedZIndex); _zIndexMap.put(allocatedZIndex, element); return allocatedZIndex; } public static void deallocateZIndex(Element element) { MapUtils.removeByValue(_zIndexMap, element); } public static int getElementZIndex(Element element) { Entry<Integer, Element> entry = MapUtils.findValue(_zIndexMap, element); if (null == entry) { return 0; } return entry.getKey(); } // TODO: What if the element does'nt have a zindex? it will return 0 and // then we'll have duplicate. public static void switchZIndex(Element element1, Element element2) { int zIndex1 = ZIndexAllocator.getElementZIndex(element1); int zIndex2 = ZIndexAllocator.getElementZIndex(element2); MapUtils.removeByValue(_zIndexMap, element1); MapUtils.removeByValue(_zIndexMap, element2); element1.getStyle().setZIndex(zIndex2); element2.getStyle().setZIndex(zIndex1); _zIndexMap.put(zIndex2, element1); _zIndexMap.put(zIndex1, element2); } public static void moveElementBelow(Element element) { ArrayList<Element> belowElements = getElementsToBelowOverlapping(element); if (null == belowElements) { // TODO: Decrease the ZIndex of that element by 1 according to the // ZIndexAllocator. return; } for (Element nextElement : belowElements) { switchZIndex(element, nextElement); } } public static void moveElementAbove(Element element) { ArrayList<Element> aboveElement = getElementsToAboveOverlapping(element); if (null == aboveElement) { // TODO: Increase the ZIndex of that element by 1 according to the // ZIndexAllocator. return; } for (Element nextElement : aboveElement) { switchZIndex(element, nextElement); } } private static ArrayList<Element> getElementsToAboveOverlapping(Element element) { ArrayList<Element> elements = new ArrayList<Element>(); int currentZIndex = getElementZIndex(element); for (Entry<Integer, Element> entry : _zIndexMap.tailMap(currentZIndex).entrySet()) { Element nextElement = entry.getValue(); if (element == nextElement) { continue; } if (false == ElementUtils.areOverlappingElements(element, nextElement)) { elements.add(nextElement); continue; } elements.add(nextElement); return elements; } return null; } private static ArrayList<Element> getElementsToBelowOverlapping(Element element) { ArrayList<Element> fooElements = new ArrayList<Element>(); int currentZIndex = getElementZIndex(element); ArrayList<Entry<Integer, Element>> array = new ArrayList<Map.Entry<Integer, Element>>(_zIndexMap .headMap(currentZIndex).entrySet()); for (int index = array.size() - 1; index >= 0; index--) { Element nextElement = array.get(index).getValue(); if (element == nextElement) { continue; } if (false == ElementUtils.areOverlappingElements(element, nextElement)) { fooElements.add(nextElement); continue; } fooElements.add(nextElement); return fooElements; } return null; } public static int getLastAllocatedZIndex() { return _nextZIndex - 1; } public static int getTopMostZIndex() { return _nextZIndex; } }