#! usr/bin/python3.9
"""
    Module initially auto generated using V5Automation files from CATIA V5 R28 on 2020-06-11 12:40:47.360445

    .. warning::
        The notes denoted "CAA V5 Visual Basic Help" are to be used as reference only.
        They are there as a guide as to how the visual basic / catscript functions work
        and thus help debugging in pycatia.

"""
from typing import Iterator
from typing import TYPE_CHECKING

from pycatia.product_structure_interfaces.product import Product
from pycatia.system_interfaces.collection import Collection
from pycatia.types.general import cat_variant

if TYPE_CHECKING:
    from pycatia.in_interfaces.document import Document


class Products(Collection):
    """
        .. note::
            :class: toggle

            CAA V5 Visual Basic Help (2020-06-11 12:40:47.360445)

                | System.IUnknown
                |     System.IDispatch
                |         System.CATBaseUnknown
                |             System.CATBaseDispatch
                |                 System.Collection
                |                     Products
                |
                | The collection of the Product objects contained in a given Product object of a
                | ProductDocument object.
                | A Product object can aggregate one or zero Products
                | collection.

    """

    def __init__(self, com_object):
        super().__init__(com_object, child_object=Product)
        self.products = com_object

    def add_component(self, i_reference_product: Product) -> Product:
        """
        .. note::
            :class: toggle

            CAA V5 Visual Basic Help (2020-06-11 12:40:47.360445))
                | o Func AddComponent(Product iReferenceProduct) As Product
                | 
                |     Creates a component and adds it to the Products collection. A component is
                |     a Product object created from another Product object used as
                |     reference.
                |
                |     Parameters:
                |
                |         iReferenceProduct
                |             The product used as reference
                | 
                |     Example:
                |
                |           The following example creates the SpareWheel component
                |           from
                |          the reference product FrontRightWheel and adds the
                |          component
                |          to the ToolKits collection.
                |
                | 
                |          Dim SpareWheel As Product
                |          Set SpareWheel = ToolKits.AddComponent(FrontRightWheel)

        :param Product i_reference_product:
        :return: Product
        :rtype: Product
        """
        return Product(self.products.AddComponent(i_reference_product.com_object))

    def add_components_from_files(self, i_files_list: tuple, i_method: str) -> None:
        """
        .. note::
            :class: toggle

            CAA V5 Visual Basic Help (2020-06-11 12:40:47.360445))
                | o Sub AddComponentsFromFiles(CATSafeArrayVariant iFilesList,
                | CATBSTR iMethod)
                | 
                |     Creates a component for each file. The components are added to the Products
                |     collection.
                |
                |     Parameters:
                |
                |         iFilesList
                |             The paths of the files used to retrieve the reference or the shape
                |             of th component
                |         iMethod
                |             A string describing the expected type of the files

        :param tuple i_files_list:
        :param str i_method:
        :return: None
        :rtype: None
        """
        return self.products.AddComponentsFromFiles(i_files_list, i_method)
        # # # # Autogenerated comment:
        # # some methods require a system service call as the methods expects a vb array object
        # # passed to it and there is no way to do this directly with python. In those cases the following code
        # # should be uncommented and edited accordingly. Otherwise completely remove all this.
        # # vba_function_name = 'add_components_from_files'
        # # vba_code = """
        # # Public Function add_components_from_files(products)
        # #     Dim iFilesList (2)
        # #     products.AddComponentsFromFiles iFilesList
        # #     add_components_from_files = iFilesList
        # # End Function
        # # """

        # # system_service = self.application.system_service
        # # return system_service.evaluate(vba_code, 0, vba_function_name, [self.com_object])

    def add_external_component(self, i_product_document: 'Document') -> Product:
        """
        .. note::
            :class: toggle

            CAA V5 Visual Basic Help (2020-06-11 12:40:47.360445))
                | o Func AddExternalComponent(Document iProductDocument) As
                | Product
                | 
                |     Creates a component from the root product of another ProductDocument
                |     object. This root product is used as a reference to create the component. The
                |     component is added to the Products collection.
                |
                |     Parameters:
                |
                |         iProductDocument
                |             The product document whose root object is to be used as reference
                |             to create the component
                | 
                |     Example:
                |
                |           The following example creates the GearBox component
                |           by
                |          referencing the GearBoxDocument and adds it
                |          to the PowerTrains collection.
                |
                | 
                |          Dim GearBox As Product
                |          Set GearBox = PowerTrains.AddExternalComponent(GearBoxDocument)

        :param Document i_product_document:
        :return: Product
        :rtype: Product
        """
        return Product(self.products.AddExternalComponent(i_product_document.com_object))

    def add_new_component(self, i_documen_type: str, i_part_number: str) -> Product:
        """
        .. note::
            :class: toggle

            CAA V5 Visual Basic Help (2020-06-11 12:40:47.360445))
                | o Func AddNewComponent(CATBSTR iDocumenType,
                | CATBSTR iPartNumber) As Product
                | 
                |     Creates a component from the root product of a new ProductDocument object.
                |     This root product is used as a reference to create the component. The component
                |     is added to the Products collection.
                |
                |     Parameters:
                |
                |         iProductDocument
                |             The product document whose root object is to be used as reference
                |             to create the component
                | 
                |     Example:
                |
                |           The following example creates the GearBox component
                |           by
                |          referencing the GearBoxDocument and adds it
                |          to the PowerTrains collection.
                |
                | 
                |          Dim GearBox As Product
                |          Set GearBox = PowerTrains.AddNewComponent(GearBoxDocument, "A120-253X-7")

        :param str i_documen_type:
        :param str i_part_number:
        :return: Product
        """
        return Product(self.products.AddNewComponent(i_documen_type, i_part_number))

    def add_new_product(self, i_part_number: str) -> Product:
        """
        .. note::
            :class: toggle

            CAA V5 Visual Basic Help (2020-06-11 12:40:47.360445))
                | o Func AddNewProduct(CATBSTR iPartNumber) As Product
                | 
                |     Creates a Product reference object. This creates a Product reference object
                |     and the associated component by specifying its type and adds it to the Products
                |     collection.
                |
                |     Parameters:
                |
                |         iPartNumber
                |             The part number of the product to be created and added to the to
                |             the collection
                |
                |     Example:
                | 
                |           The following example creates the Engine product
                |          and adds the created component to the PowerTrains
                |          collection.
                |
                | 
                |          Dim Engine As Product
                |          Set Engine = PowerTrains.AddNewProduct(V6Engine)

        :param str i_part_number:
        :return: Product
        :rtype: Product
        """
        return Product(self.products.AddNewProduct(i_part_number))

    def item(self, i_index: cat_variant) -> Product:
        """
        .. note::
            :class: toggle

            CAA V5 Visual Basic Help (2020-06-11 12:40:47.360445))
                | o Func Item(CATVariant iIndex) As Product
                | 
                |     Returns a product from its index in the Products
                |     collection.
                |
                |     Parameters:
                |
                |         iIndex
                |             The index of the product to retrieve in the collection of products.
                |             This index can either be the rank of the product in the collection or the name
                |             you assign to the product. As a numerics, this index is the rank of the product
                |             in the collection. The index of the first product in the collection is 1, and
                |             the index of the last product is Count. As a string, it is the name you
                |             assigned to the product using the
                | 
                |         AnyObject.Name property
                |     Returns:
                |         The retrieved product
                |     Example:
                | 
                |           The following example returns in ThisProduct the third
                |           product,
                |          and in ThatProduct the product named
                |          Wheel in the CarParts product collection.
                |
                | 
                |          Dim ThisProduct As Product
                |          Set ThisProduct = CarParts.Item(3)
                |          Dim ThatProduct As Product
                |          Set ThatProduct = CarParts.Item("Wheel")

        :param cat_variant i_index:
        :return: Product
        :rtype: Product
        """
        return Product(self.products.Item(i_index))

    def remove(self, i_index: cat_variant) -> None:
        """
        .. note::
            :class: toggle

            CAA V5 Visual Basic Help (2020-06-11 12:40:47.360445))
                | o Sub Remove(CATVariant iIndex)
                | 
                |     Removes a product from the Products collection.
                |
                |     Parameters:
                |
                |         iIndex
                |             The index of the product to remove. This index can either be the
                |             rank of the product in the collection or the name you assigned to the product.
                |             As a numerics, this index is the rank of the product in the collection. The
                |             index of the first product in the collection is 1, and the index of the last
                |             product is Count. As a string, it is the name you assigned to the product using
                |             the
                | 
                |         AnyObject.Name property
                |     Example:
                | 
                |           The following example removes the sixth product and the product
                |           named
                |          LeftRearDisc from the Brakes product collection.
                |
                | 
                |          Brakes.Remove(6)
                |          Brakes.Remove("LeftRearDisc")

        :param cat_variant i_index:
        :return: None
        :rtype: None
        """
        return self.products.Remove(i_index)
        # # # # Autogenerated comment:
        # # some methods require a system service call as the methods expects a vb array object
        # # passed to it and there is no way to do this directly with python. In those cases the following code
        # # should be uncommented and edited accordingly. Otherwise completely remove all this.
        # # vba_function_name = 'remove'
        # # vba_code = """
        # # Public Function remove(products)
        # #     Dim iIndex (2)
        # #     products.Remove iIndex
        # #     remove = iIndex
        # # End Function
        # # """

        # # system_service = self.application.system_service
        # # return system_service.evaluate(vba_code, 0, vba_function_name, [self.com_object])

    def replace_component(self, i_old_component: Product, i_file_path: str, i_multi_instances: bool) -> Product:
        """
        .. note::
            :class: toggle

            CAA V5 Visual Basic Help (2020-06-11 12:40:47.360445))
                | o Func ReplaceComponent(Product iOldComponent,
                | CATBSTR iFilePath,
                | boolean iMultiInstances) As Product
                | 
                |     Creates a component which replace the given one.
                |
                |     Parameters:
                |
                |         iOldComponent
                |             The component which will be replaced
                |         iFilePath
                |             the document to replace with
                |         iMultiInstances
                |             Parameter to set to True if all instances are to be replaced, or to
                |             False otherwise. Returns the component replacing
                |             iOldComponent
                |
                |
                |             Note:
                |             Part Number conflict will be resolved
                |             automatically.

        :param Product i_old_component:
        :param str i_file_path:
        :param bool i_multi_instances:
        :return: Product
        :rtype: Product
        """
        return Product(self.products.ReplaceComponent(i_old_component.com_object, i_file_path, i_multi_instances))

    def replace_product(self, i_old_component: Product, i_new_reference: Product, i_multi_instances: bool) -> Product:
        """
        .. note::
            :class: toggle

            CAA V5 Visual Basic Help (2020-06-11 12:40:47.360445))
                | o Func ReplaceProduct(Product iOldComponent,
                | Product iNewReference,
                | boolean iMultiInstances) As Product
                | 
                |     Creates a component which replace the given one.
                |
                |     Parameters:
                |
                |         iOldComponent
                |             The component which will be replaced
                |         iNewReference
                |             the reference whom the old copmponent will be reconnected
                |
                |         iMultiInstances
                |             Parameter to set to True if all instances are to be replaced, or to
                |             False otherwise. Returns the component replacing
                |             iOldComponent

        :param Product i_old_component:
        :param Product i_new_reference:
        :param bool i_multi_instances:
        :return: Product
        :rtype: Product
        """
        return Product(
            self.products.ReplaceProduct(
                i_old_component.com_object,
                i_new_reference.com_object,
                i_multi_instances
            )
        )

    def __len__(self):
        return self.count

    def __getitem__(self, n: int) -> Product:
        if (n + 1) > self.count:
            raise StopIteration

        return Product(self.products.item(n + 1))

    def __iter__(self) -> Iterator[Product]:
        for i in range(self.count):
            yield self.child_object(self.com_object.item(i + 1))

    def __repr__(self):
        return f'Products(name="{self.name}")'
