/******************************************************************************* * See the NOTICE file distributed with this work for additional information * regarding copyright ownership. * * 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 hr.fer.zemris.vhdllab.applets.editor.schema2.model; import hr.fer.zemris.vhdllab.applets.editor.schema2.enums.EComponentType; import hr.fer.zemris.vhdllab.applets.editor.schema2.exceptions.DuplicateKeyException; import hr.fer.zemris.vhdllab.applets.editor.schema2.exceptions.OverlapException; import hr.fer.zemris.vhdllab.applets.editor.schema2.exceptions.UnknownKeyException; import hr.fer.zemris.vhdllab.applets.editor.schema2.interfaces.ISchemaComponent; import hr.fer.zemris.vhdllab.applets.editor.schema2.interfaces.ISchemaComponentCollection; import hr.fer.zemris.vhdllab.applets.editor.schema2.misc.Caseless; import hr.fer.zemris.vhdllab.applets.editor.schema2.misc.PlacedComponent; import hr.fer.zemris.vhdllab.applets.editor.schema2.misc.XYLocation; import java.awt.Rectangle; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Map.Entry; /** * Jednostavna kolekcija komponenti * u smislu da ima O(n) slozenost * dohvata po lokaciji. * Obavlja svoj posel bez obzira na to. * * @author brijest * */ public class SimpleSchemaComponentCollection implements ISchemaComponentCollection { /* private fields */ private Map<Caseless, PlacedComponent> components; private List<PlacedComponent> insertlist; private XYLocation loc; /* ctors */ public SimpleSchemaComponentCollection() { components = new HashMap<Caseless, PlacedComponent>(); insertlist = new LinkedList<PlacedComponent>(); loc = new XYLocation(); } /* methods */ public void addComponent(int x, int y, ISchemaComponent component) throws DuplicateKeyException, OverlapException { if (components.containsKey(component.getName())) throw new DuplicateKeyException(); // TODO: eventualna provjera overlappinga dode ovdje PlacedComponent wrapper = new PlacedComponent(); wrapper.comp = component; wrapper.pos = new XYLocation(x, y); components.put(component.getName(), wrapper); insertlist.add(wrapper); } public void addComponentAt(int x, int y, ISchemaComponent component, int index) throws DuplicateKeyException, OverlapException { if (components.containsKey(component.getName())) throw new DuplicateKeyException(); if (index < 0 || index > insertlist.size()) throw new IndexOutOfBoundsException(); // TODO: eventualna provjera overlappinga dode ovdje PlacedComponent wrapper = new PlacedComponent(); wrapper.comp = component; wrapper.pos = new XYLocation(x, y); components.put(component.getName(), wrapper); insertlist.add(index, wrapper); } public int getComponentIndex(Caseless name) throws UnknownKeyException { if (!components.containsKey(name)) throw new UnknownKeyException(); int count = 0; for (PlacedComponent plc : insertlist) { if (plc.comp.getName().equals(name)) return count; count++; } throw new IllegalStateException("Component exists but not found during iteration."); } public void reinsertComponent(Caseless name, int x, int y) throws UnknownKeyException, OverlapException { if (!components.containsKey(name)) throw new UnknownKeyException(); // TODO eventualna provjera overlappinga PlacedComponent plc = components.get(name); components.remove(name); plc.pos.x = x; plc.pos.y = y; components.put(name, plc); } public void renameComponent(Caseless name, Caseless updatedname) throws UnknownKeyException, DuplicateKeyException { if (!components.containsKey(name)) throw new UnknownKeyException(); if (components.containsKey(updatedname)) throw new DuplicateKeyException(); PlacedComponent plc = components.get(name); components.remove(name); plc.comp.setName(updatedname); components.put(updatedname, plc); } public int size() { return components.size(); } public boolean containsAt(int x, int y, int dist) { PlacedComponent plc; loc.x = x; loc.y = y; for (Entry<Caseless, PlacedComponent> entry : components.entrySet()) { plc = entry.getValue(); if (loc.in(plc.pos.x - dist, plc.pos.y - dist, plc.comp.getWidth() + 2 * dist, plc.comp.getHeight() + 2 * dist)) return true; } return false; } public boolean containsName(Caseless componentName) { return components.containsKey(componentName); } public ISchemaComponent fetchComponent(int x, int y, int dist) { ISchemaComponent found = null; int mindist = dist + 1; loc.x = x; loc.y = y; for (Entry<Caseless, PlacedComponent> entry : components.entrySet()) { PlacedComponent plc = entry.getValue(); int wdt = plc.comp.getWidth(), hgt = plc.comp.getHeight(); if (loc.in(plc.pos.x, plc.pos.y, wdt, hgt)) return plc.comp; int plcdist = plc.pos.x - loc.x; if (loc.y >= (plc.pos.y - dist) && loc.y <= (plc.pos.y + hgt + dist)) { if (plcdist < mindist && plcdist >= 0) { mindist = plcdist; found = plc.comp; } plcdist = loc.x - (plc.pos.x + wdt); if (plcdist < mindist && plcdist >= 0) { mindist = plcdist; found = plc.comp; } } if (loc.x >= (plc.pos.x - dist) && loc.x <= (plc.pos.x + wdt + dist)) { plcdist = plc.pos.y - loc.y; if (plcdist < mindist && plcdist >= 0) { mindist = plcdist; found = plc.comp; } plcdist = loc.y - (plc.pos.y + hgt); if (plcdist < mindist && plcdist >= 0) { mindist = plcdist; found = plc.comp; } } } return found; } public ISchemaComponent fetchComponent(Caseless componentName) { PlacedComponent placedcomp = components.get(componentName); if (placedcomp == null) return null; return placedcomp.comp; } public Set<ISchemaComponent> fetchComponents(EComponentType componentType) { Set<ISchemaComponent> comps = new LinkedHashSet<ISchemaComponent>(); for (PlacedComponent plc : insertlist) { if (plc.comp.getComponentType().equals(componentType)) comps.add(plc.comp); } return comps; } public XYLocation getComponentLocation(Caseless componentName) { PlacedComponent cpw = components.get(componentName); if (cpw == null) return null; return new XYLocation(cpw.pos); } public Rectangle getComponentBounds(Caseless componentName) { PlacedComponent cpw = components.get(componentName); if (cpw == null) return null; Rectangle bounds = new Rectangle(); bounds.x = cpw.pos.x; bounds.y = cpw.pos.y; bounds.width = cpw.comp.getWidth(); bounds.height = cpw.comp.getHeight(); return bounds; } public void removeComponent(Caseless name) throws UnknownKeyException { if (!components.containsKey(name)) throw new UnknownKeyException(); components.remove(name); Iterator<PlacedComponent> itp = insertlist.iterator(); while (itp.hasNext()) { if (itp.next().comp.getName().equals(name)) { itp.remove(); break; } } } public int distanceTo(Caseless name, int xfrom, int yfrom) { PlacedComponent plc = components.get(name); // no such component if (plc == null) return ISchemaComponentCollection.NO_COMPONENT; // is click within component int w = plc.comp.getWidth(), h = plc.comp.getHeight(); if (xfrom >= plc.pos.x && yfrom >= plc.pos.y && xfrom <= (plc.pos.x + w) && yfrom <= (plc.pos.y + h)) { return 0; } // click is outside component int xmin, ymin; if (xfrom < plc.pos.x) { xmin = plc.pos.x - xfrom; } else { xmin = xfrom - (plc.pos.x + w); } if (yfrom < plc.pos.y) { ymin = plc.pos.y - yfrom; } else { ymin = yfrom - (plc.pos.y + h); } return (xmin < ymin) ? (xmin) : (ymin); } public Set<Caseless> getComponentNames() { return components.keySet(); } public Iterator<PlacedComponent> iterator() { return insertlist.iterator(); } public void clear() { components.clear(); } }