contract PledgeFactory is RBACOperator {
  using AddressUtils for address;

  // initial type of pledge contract.
  string internal constant INIT_TOKEN_NAME = "UNKNOWN";

  mapping(uint256 => EscrowPledge) internal pledgeEscrowById;
  // pledge number unique screening.
  mapping(uint256 => bool) internal isPledgeId;

  /**
   * @dev Pledge guarantee statistics.
   */
  struct EscrowPledge {
    address pledgeContract;
    string tokenName;
  }

  /**
   * Event for createOrderContract logging.
   * @param pledgeId management contract id.
   * @param newPledgeAddress pledge management contract address.
   */
  event CreatePledgeContract(uint256 indexed pledgeId, address newPledgeAddress);


  /**
   * @dev Create a pledge subcontract
   * @param _pledgeId index number of the pledge contract.
   */
  function createPledgeContract(uint256 _pledgeId, address _escrowPartner) public onlyPartner returns(bool) {
    require(_pledgeId > 0 && !isPledgeId[_pledgeId] && _escrowPartner!=address(0));

    // Give the pledge contract the right to update statistics.
    PledgeContract pledgeAddress = new PledgeContract(_pledgeId, address(this),partner);
    pledgeAddress.transferOwnership(_escrowPartner);
    addOperater(address(pledgeAddress));

    // update pledge contract info
    isPledgeId[_pledgeId] = true;
    pledgeEscrowById[_pledgeId] = EscrowPledge(pledgeAddress, INIT_TOKEN_NAME);

    emit CreatePledgeContract(_pledgeId, address(pledgeAddress));
    return true;
  }



  /**
   * @dev Batch create a pledge subcontract
   * @param _pledgeIds index number of the pledge contract.
   */
  function batchCreatePledgeContract(uint256[] _pledgeIds, address _escrowPartner) public onlyPartner {
    require(_pledgeIds.length > 0 && _escrowPartner.isContract());
    for (uint i = 0; i < _pledgeIds.length; i++) {
      require(createPledgeContract(_pledgeIds[i],_escrowPartner));
    }
  }

  /**
   * @dev Use the index to get the basic information of the corresponding pledge contract.
   * @param _pledgeId index number of the pledge contract
   */
  function getEscrowPledge(uint256 _pledgeId) public view returns(string tokenName, address pledgeContract) {
    require(_pledgeId > 0);
    tokenName = pledgeEscrowById[_pledgeId].tokenName;
    pledgeContract = pledgeEscrowById[_pledgeId].pledgeContract;
  }




  // -----------------------------------------
  // Internal interface (Only the pledge contract has authority to operate)
  // -----------------------------------------


  /**
   * @dev Configure permissions to operate on the token pool.
   * @param _tokenPool token pool contract address.
   * @param _pledge pledge contract address.
   */
  function tokenPoolOperater(address _tokenPool, address _pledge) public hasOperationPermission {
    require(_pledge != address(0) && address(msg.sender).isContract() && address(msg.sender) == _pledge);
    PledgePoolBase(_tokenPool).addOperater(_pledge);
  }


  /**
   * @dev Update the basic data of the pledge contract.
   * @param _pledgeId index number of the pledge contract.
   * @param _tokenName pledge contract supported token type.
   */
  function updatePledgeType(uint256 _pledgeId, string _tokenName) public hasOperationPermission {
    require(_pledgeId > 0 && bytes(_tokenName).length > 0 && address(msg.sender).isContract());
    pledgeEscrowById[_pledgeId].tokenName = _tokenName;
  }
}
/**
 * @title PledgeFactory
 * @dev Pledge factory contract.
 * @dev Specially provides the pledge guarantee creation and the statistics function.
 */
function createPledgeContract(uint256 _pledgeId, address _escrowPartner) public onlyPartner returns(bool) {
  require(_pledgeId > 0 && !isPledgeId[_pledgeId] && _escrowPartner!=address(0));

  // Give the pledge contract the right to update statistics.
  PledgeContract pledgeAddress = new PledgeContract(_pledgeId, address(this),partner);
  pledgeAddress.transferOwnership(_escrowPartner);
  addOperater(address(pledgeAddress));

  // update pledge contract info
  isPledgeId[_pledgeId] = true;
  pledgeEscrowById[_pledgeId] = EscrowPledge(pledgeAddress, INIT_TOKEN_NAME);

  emit CreatePledgeContract(_pledgeId, address(pledgeAddress));
  return true;
}

/**
 * @dev Create a pledge subcontract
 * @param _pledgeId index number of the pledge contract.
 */