contract ChainDrawingsCore is ChainDrawingsGeneration {
  address public newContractAddress;
  BatchCreateDrawingsInterface public batchCreateDrawings;
  
  constructor() public {
    paused = true;
    owner = msg.sender;
    _createDrawings("-1",  "-1", address(0), "https://chain.chuangyipaobu.com"); //创建合约的时候，需要把默认的0位排除掉
  }
  
  //设置批量导入合约地址
  function setBatchCreateDrawingsAddress(address _address) external onlyOwner {
    BatchCreateDrawingsInterface candidateContract = BatchCreateDrawingsInterface(_address);
    require(candidateContract.isBatchCreateDrawings());

    // Set the new contract address
    batchCreateDrawings = candidateContract;
  }

  //批量生成内部链跑图
  function batchCreateInternalDrawings() internal onlyOwner {
    require(batchCreateDrawings != address(0));

    bytes32 chainID;
    uint256 startingPrice;
    uint256 endingPrice;
    uint256 duration;
    string memory metaUrl;
    uint index = 0;

    while(index < 20){	//避免死循环和执行失败，最多一次创建20个链跑图
      (chainID, startingPrice, endingPrice, duration, metaUrl) = batchCreateDrawings.getInternalDrawings(index++);
      if(chainID == "0"){
        return;
      }

      if(chainIDToTokenID[chainID] > 0){
        continue;
      }
    
      createInternalAuction(chainID, "跑地图", startingPrice, endingPrice, duration, metaUrl);
    }
  }

  //批量生成原创者链跑图
  function batchCreateAuthorDrawings() internal onlyOwner {
    require(batchCreateDrawings != address(0));

    bytes32 chainID;
    bytes32 author;
    address owner; 
    string memory metaUrl;
    uint index = 0;

    while(index < 20){	//避免死循环和执行失败，最多一次创建20个链跑图
      (chainID, author, owner, metaUrl) = batchCreateDrawings.getAuthorDrawings(index++);
      if(chainID == "0"){
        return;
      }
      if(chainIDToTokenID[chainID] > 0){
        continue;
      }  

      createAuthorDrawings(chainID, author, owner, metaUrl);
    }
  }

  //批量生成链跑图
  function batchCreateDrawings() external onlyOwner {
    batchCreateInternalDrawings();
    batchCreateAuthorDrawings();
  }

  //永久终止合约
  function setNewAddress(address _newAddress) external onlyOwner whenPaused {
    newContractAddress = _newAddress;
    emit ContractUpgrade(_newAddress);
  }

  function() external payable {
    require(msg.sender == address(saleAuction));
  }

  function getChainDrawings(uint256 _id) public view returns(
      uint256 tokenID,
      bytes32 chainID,  //链跑图ID。（对应链跑图ID、创意跑步App内跑图ID）
      bytes32 author,   //原创者名称
      uint256 createTime
  ) {
    ChainDrawings storage drawing = drawings[_id];

    tokenID = _id;
    chainID = drawing.chainID;
    author = drawing.author;
    createTime = drawing.createTime;
  }

  //获取主合约地址
  function getCoreAddress() external view returns(address){
    return address(this);
  }

  //获取拍卖合约地址
  function getSaleAuctionAddress() external view returns(address){
    return address(saleAuction);
  }

  //获取批量导入合约地址
  function getBatchCreateDrawingsAddress() external view returns(address){
    return address(batchCreateDrawings);
  }

  function unpause() public onlyOwner whenPaused {
    require(saleAuction != address(0));
    require(newContractAddress == address(0));

    super.unpause();
  }

  //通过跑图chainID，获取链跑图信息
  function getChainDrawingsByChainID(bytes32 _chainID) external view returns(
      uint256 tokenID,
      bytes32 chainID,        //链跑图ID。（对应链跑图ID、创意跑步App内跑图ID）
      bytes32 author,   //原创者名称
      uint256 createTime         //链跑图创建时间
  ){
    tokenID = chainIDToTokenID[_chainID];
    return getChainDrawings(tokenID);
  }

  function getFund() external view returns (uint256 balance){
    return address(this).balance;
  }

  //获取用户名下所有的TokenID（包含正在出售的）
  function getAllTokensOfUser(address _owner) public view returns (uint256[]){
    uint256[] memory ownerTokensNonAuction = this.tokensOfOwner(_owner);
    uint256[] memory ownerTokensAuction = saleAuction.getAuctionTokenIDsOfOwner(_owner);
    
    uint length1 = ownerTokensNonAuction.length;
    uint length2 = ownerTokensAuction.length;
    uint length = length1 + length2;

    if(length == 0) return;

    uint256[] memory result = new uint[](length);
    uint index = 0;

    for (uint i=0; i<length2; i++) {
      result[index++] = ownerTokensAuction[i];
    }
    for (uint j=0; j<length1; j++) {
      result[index++] = ownerTokensNonAuction[j];
    }
    
    return result;
  }
  
  //获取用户名下所有的ChainID（包含正在出售的）
  function getAllChainIDsOfUser(address _owner) external view returns (bytes32[]){
    uint256[] memory ownerTokens = this.getAllTokensOfUser(_owner);
    uint len = ownerTokens.length;
 
    if(len == 0) return;

    bytes32[] memory ownerChainIDs = new bytes32[](len);
    for (uint i=0; i<len; i++) {
      ChainDrawings storage drawing = drawings[ownerTokens[i]];
      ownerChainIDs[i] = drawing.chainID;
    }
    return ownerChainIDs;
  }

  //获取用户名下跑图总数（包含正在出售的）
  function getTokensCountOfUser(address _owner) external view returns (uint256){
    uint256[] memory ownerTokensNonAuction = this.tokensOfOwner(_owner);
    uint256[] memory ownerTokensAuction = saleAuction.getAuctionTokenIDsOfOwner(_owner);
    
    uint length1 = ownerTokensNonAuction.length;
    uint length2 = ownerTokensAuction.length;
    return length1 + length2;
  }
}
function setNewAddress(address _newAddress) external onlyOwner whenPaused {
  newContractAddress = _newAddress;
  emit ContractUpgrade(_newAddress);
}

//永久终止合约