# Copyright (c) 2018 Manfred Moitzi
# License: MIT License
from typing import TYPE_CHECKING, Iterable, cast
from ezdxf.lldxf.const import DXFValueError, DXFKeyError

if TYPE_CHECKING:
    from ezdxf.eztypes import DXFObject, Dictionary, Drawing, ObjectsSection


class ObjectCollection:
    def __init__(self, doc: 'Drawing', dict_name: str = 'ACAD_MATERIAL', object_type: str = 'MATERIAL'):
        self.doc = doc  # type: Drawing
        self.object_type = object_type  # type: str
        self.object_dict = doc.rootdict.get_required_dict(dict_name)  # type: Dictionary

    @property
    def objects(self) -> 'ObjectsSection':
        return self.doc.objects

    def __iter__(self) -> Iterable['DXFObject']:
        return self.object_dict.items()

    def __len__(self) -> int:
        return len(self.object_dict)

    def __contains__(self, name: str) -> bool:
        return name in self.object_dict

    def __getitem__(self, item):
        return self.get(item)

    def get(self, name: str) -> 'DXFObject':
        """
        Get object by name.

        Args:
            name: object name as string

        Raises:
            DXFKeyError: if name does not exist

        """
        return cast('DXFObject', self.object_dict.get(name))

    def new(self, name: str) -> 'DXFObject':
        """
        Create a new object of type `self.object_type` and store its handle in the object manager dictionary.

        Args:
            name: name of new object as string

        Returns:
            new object of type `self.object_type`

        Raises:
            DXFValueError: if object name already exist

        (internal API)

        """
        if name in self.object_dict:
            raise DXFValueError('{} entry {} already exists.'.format(self.object_type, name))
        return self._new(name, dxfattribs={'name': name})

    def _new(self, name: str, dxfattribs: dict) -> 'DXFObject':
        owner = self.object_dict.dxf.handle
        dxfattribs['owner'] = owner
        obj = self.objects.add_dxf_object_with_reactor(self.object_type, dxfattribs=dxfattribs)
        self.object_dict.add(name, obj)
        return cast('DXFObject', obj)

    def delete(self, name: str) -> None:
        try:
            obj = self.object_dict.get(name)
        except DXFKeyError:
            return
        else:
            self.object_dict.discard(name)
            self.objects.delete_entity(obj)

    def clear(self) -> None:
        """
        Delete all entries.

        """
        self.object_dict.clear()

@@ -13,16 +13,21 @@
 (c) 2018
+-2020
  Manfred
@@ -34,16 +34,16 @@
  Moitzi%0A
-
 # Licens
@@ -357,16 +357,33 @@
 TERIAL',
+%0A                
  object_
@@ -427,31 +427,25 @@
 .doc
- = doc  # type
 : 
+'
 Drawing
+' = doc
 %0A   
@@ -465,16 +465,21 @@
 ect_type
+: str
  = objec
@@ -488,21 +488,8 @@
 type
-  # type: str
 %0A   
@@ -509,16 +509,30 @@
 ect_dict
+: 'Dictionary'
  = doc.r
@@ -561,38 +561,31 @@
 ict(
-dict_name)  # type: Dictionary
+%0A            dict_name)
 %0A%0A  
@@ -1038,24 +1038,16 @@
      %22%22%22
-%0A       
  Get obj
@@ -1310,23 +1310,16 @@
      %22%22%22
-%0A      
   Create
@@ -1379,16 +1379,24 @@
 s handle
+%0A       
  in the 
@@ -1735,10 +1735,44 @@
 ror(
-'%7B
+%0A                f'%7Bself.object_type
 %7D en
@@ -1776,16 +1776,20 @@
  entry %7B
+name
 %7D alread
@@ -1802,39 +1802,8 @@
 ts.'
-.format(self.object_type, name)
 )%0A  
@@ -2058,16 +2058,29 @@
 reactor(
+%0A            
 self.obj
@@ -2479,24 +2479,16 @@
      %22%22%22
-%0A       
  Delete 
@@ -2499,25 +2499,16 @@
 entries.
-%0A%0A       
  %22%22%22%0A   

reformat code to 80 cols