use std::borrow::Borrow;
use std::hash::Hash;
use crate::layout::types::UInt;
use iron_shapes::transform::SimpleTransform;
use iron_shapes::CoordinateType;
pub trait LayoutBase {
type Coord: CoordinateType;
type NameType: Eq + Hash + From<String> + Clone + Borrow<String> + Borrow<str>;
type LayerId: Eq + Hash + Clone;
type CellId: Eq + Hash + Clone;
type CellInstId: Eq + Hash + Clone;
fn new() -> Self;
fn cell_by_name<N: ?Sized + Eq + Hash>(&self, name: &N) -> Option<Self::CellId>
where Self::NameType: Borrow<N>;
fn each_cell<'a>(&'a self) -> Box<dyn Iterator<Item=Self::CellId> + 'a>;
fn each_cell_instance<'a>(&'a self, cell: &Self::CellId) -> Box<dyn Iterator<Item=Self::CellInstId> + 'a>;
fn each_dependent_cell<'a>(&'a self, cell: &Self::CellId) -> Box<dyn Iterator<Item=Self::CellId> + 'a>;
fn each_cell_dependency<'a>(&'a self, cell: &Self::CellId) -> Box<dyn Iterator<Item=Self::CellId> + 'a>;
fn parent_cell(&self, circuit_instance: &Self::CellInstId) -> Self::CellId;
fn template_cell(&self, circuit_instance: &Self::CellInstId) -> Self::CellId;
fn find_layer(&self, index: UInt, datatype: UInt) -> Option<Self::LayerId>;
}
pub trait LayoutEdit
where Self: LayoutBase {
fn find_or_create_layer(&mut self, index: UInt, datatype: UInt) -> Self::LayerId;
fn create_cell(&mut self, name: Self::NameType) -> Self::CellId;
fn remove_cell(&mut self, cell_id: &Self::CellId);
fn create_cell_instance(&mut self,
parent_cell: &Self::CellId,
template_cell: &Self::CellId,
name: Option<Self::NameType>,
transform: SimpleTransform<Self::Coord>) -> Self::CellInstId;
fn remove_cell_instance(&mut self, id: &Self::CellInstId);
}