contract collectionFactoryV2 is FactoryInterface, Ownable {
    using Strings for uint256;
    string private _contractname;
    string private _uri;
    constructor(){
      _contractname = "[Cryptovoxels] Collection Factory V2";
      _uri = 'https://www.cryptovoxels.com/c/';
    }

    function name() public view override returns(string memory){
      return _contractname;
    }

    function launchCollection(uint256 collection_id,string memory _name) public override returns (address collection) {
        require(idToCollection[collection_id] == address(0),'Collection already exists');
        string memory uri = collectionURI(collection_id);
        cvCollectibles newCollection = new cvCollectibles(uri,_name);
        address _collection = address(newCollection);
        require(_collection != address(0),'Zero address not allowed');
        require(_collection != address(this));

        // set collection to Id
        collectionToId[_collection] = collection_id;
        // set Id to collection
        idToCollection[collection_id] = _collection;
        // set collection to index in collectionsList
        collectionToIndex[_collection] = collectionsList.length;
        // Push into the collectionsList
        collectionsList.push(_collection);
        
        NewCollectionCreated(_collection,msg.sender,collection_id);

        // transfer ownership
        newCollection.transferOwnership(msg.sender);
        return _collection;
    }

    function addCollection(address _collection, uint256 collection_id) public override onlyOwner {
        require(_collection != address(0),'Zero address is not allowed');
        require(idToCollection[collection_id] == address(0),'Collection already exists');
        require(_collection != address(this));
        address o = cvCollectibles(_collection).owner();
        // add to COllection to Id
        collectionToId[_collection] = collection_id;
        // add to Id to collection
        idToCollection[collection_id] = _collection;
        // add collection to index
        collectionToIndex[_collection] = collectionsList.length;
        // add to collection list
        collectionsList.push(_collection);
        NewCollectionCreated(_collection,o,collection_id);
    }

    function getCollectionsCount() public override view returns (uint256 collectionscount) {
        return collectionsList.length;
    }

    function getIdFromCollection(address _collection) public override view returns (uint256 id) {
        return collectionToId[_collection];
    }
    function getCollectionFromId(uint256 _id) public override view returns (address collection) {
    return idToCollection[_id];
    }

        /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function collectionURI(uint256 collection_id)
        internal
        view
        returns (string memory)
    {
        string memory baseURI = _baseURI();
        return
            bytes(baseURI).length > 0
                ? string(abi.encodePacked(baseURI, collection_id.toString(),'/{id}'))
                : "";
    }

    function _baseURI() internal view returns (string memory) {
        return _uri;
    }

    function setBaseURI(string calldata newURI) public onlyOwner {
        _uri = newURI;
    }

    function migrateOldFactory(address oldcontract,uint256 quantity) external onlyOwner {
        require(oldcontract != address(0),'Zero address is not allowed');
        uint256 currentCollectionsCount;
        currentCollectionsCount = getCollectionsCount();
        FactoryInterface factory = FactoryInterface(oldcontract);
        uint256 previousCollectionsCount;
        previousCollectionsCount = factory.getCollectionsCount();
        for (uint256 i = currentCollectionsCount; i <(currentCollectionsCount+quantity); i++) {
            if(i>previousCollectionsCount){
                break;
            }
            uint256 collection_id;
            address collection;
            collection = factory.collectionsList(i);
            collection_id = factory.getIdFromCollection(collection);

            addCollection(collection, collection_id);
        }
    }
}
function collectionURI(uint256 collection_id)
    internal
    view
    returns (string memory)
{
    string memory baseURI = _baseURI();
    return
        bytes(baseURI).length > 0
            ? string(abi.encodePacked(baseURI, collection_id.toString(),'/{id}'))
            : "";
}

/**
 * @dev See {IERC721Metadata-tokenURI}.
 */