contract KStarCoinBasic is ERC827Token, MultiOwnable {
    using SafeMath for uint256;
    using SafeERC20 for ERC20Basic;
    using strings for *;

    // KStarCoin Distribution
    // - Crowdsale : 9%(softcap) ~ 45%(hardcap)
    // - Reserve: 15%
    // - Team: 10%
    // - Advisors & Partners: 5%
    // - Bounty Program + Ecosystem : 25% ~ 61%
    uint256 public capOfTotalSupply;
    uint256 public constant INITIAL_SUPPLY= 30e6 * 1 ether; // Reserve(15) + Team(10) + Advisors&Patners(5)

    uint256 public crowdsaleRaised;
    uint256 public constant CROWDSALE_HARDCAP= 45e6 * 1 ether; // Crowdsale(Max 45)

    /**
     * @dev Function to increase capOfTotalSupply in the next phase of KStarCoin's ecosystem
     */
    function increaseCap(uint256 _addedValue) onlyOwner public returns (bool) {
        require(_addedValue >= 100e6 * 1 ether);
        capOfTotalSupply = capOfTotalSupply.add(_addedValue);
        return true;
    }
    
    /**
     * @dev Function to check whether the current supply exceeds capOfTotalSupply
     */
    function checkCap(uint256 _amount) public view returns (bool) {
        return (totalSupply_.add(_amount) <= capOfTotalSupply);
    }
    
    //> for ERC20
    function transfer(address _to, uint256 _value) public returns (bool) {
        require(super.transfer(_to, _value));
        KSC_Send(msg.sender, _to, _value, "");
        KSC_Receive(_to, msg.sender, _value, "");
        return true;
    }
    
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
        require(super.transferFrom(_from, _to, _value));
        KSC_SendTo(_from, _to, _value, "");
        KSC_ReceiveFrom(_to, _from, _value, "");
        return true;
    }
    
    function approve(address _to, uint256 _value) public returns (bool) {
        require(super.approve(_to, _value));
        KSC_Approve(msg.sender, _to, _value, "");
        return true;
    }
    
    // additional StandardToken method of zeppelin-solidity
    function increaseApproval(address _to, uint _addedValue) public returns (bool) {
        require(super.increaseApproval(_to, _addedValue));
        KSC_ApprovalInc(msg.sender, _to, _addedValue, "");
        return true;
    }
    
    // additional StandardToken method of zeppelin-solidity
    function decreaseApproval(address _to, uint _subtractedValue) public returns (bool) {
        require(super.decreaseApproval(_to, _subtractedValue));
        KSC_ApprovalDec(msg.sender, _to, _subtractedValue, "");
        return true;
    }
	//<
    
    //> for ERC827
    function transfer(address _to, uint256 _value, bytes _data) public returns (bool) {
        return transfer(_to, _value, _data, "");
    }
    
    function transferFrom(address _from, address _to, uint256 _value, bytes _data) public returns (bool) {
        return transferFrom(_from, _to, _value, _data, "");
    }
    
    function approve(address _to, uint256 _value, bytes _data) public returns (bool) {
        return approve(_to, _value, _data, "");
    }
    
    // additional StandardToken method of zeppelin-solidity
    function increaseApproval(address _to, uint _addedValue, bytes _data) public returns (bool) {
        return increaseApproval(_to, _addedValue, _data, "");
    }
    
    // additional StandardToken method of zeppelin-solidity
    function decreaseApproval(address _to, uint _subtractedValue, bytes _data) public returns (bool) {
        return decreaseApproval(_to, _subtractedValue, _data, "");
    }
	//<
    
    //> notation for ERC827
    function transfer(address _to, uint256 _value, bytes _data, string _note) public returns (bool) {
        require(super.transfer(_to, _value, _data));
        KSC_Send(msg.sender, _to, _value, _note);
        KSC_Receive(_to, msg.sender, _value, _note);
        return true;
    }
    
    function transferFrom(address _from, address _to, uint256 _value, bytes _data, string _note) public returns (bool) {
        require(super.transferFrom(_from, _to, _value, _data));
        KSC_SendTo(_from, _to, _value, _note);
        KSC_ReceiveFrom(_to, _from, _value, _note);
        return true;
    }
    
    function approve(address _to, uint256 _value, bytes _data, string _note) public returns (bool) {
        require(super.approve(_to, _value, _data));
        KSC_Approve(msg.sender, _to, _value, _note);
        return true;
    }
    
    function increaseApproval(address _to, uint _addedValue, bytes _data, string _note) public returns (bool) {
        require(super.increaseApproval(_to, _addedValue, _data));
        KSC_ApprovalInc(msg.sender, _to, _addedValue, _note);
        return true;
    }
    
    function decreaseApproval(address _to, uint _subtractedValue, bytes _data, string _note) public returns (bool) {
        require(super.decreaseApproval(_to, _subtractedValue, _data));
        KSC_ApprovalDec(msg.sender, _to, _subtractedValue, _note);
        return true;
    }
	//<
      
    /**
     * @dev Function to mint coins
     * @param _to The address that will receive the minted coins.
     * @param _amount The amount of coins to mint.
     * @return A boolean that indicates if the operation was successful.
     * @dev reference : https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/MintableToken.sol
     */
    function mint(address _to, uint256 _amount) onlyOwner internal returns (bool) {
        require(_to != address(0));
        require(checkCap(_amount));

        totalSupply_= totalSupply_.add(_amount);
        balances[_to]= balances[_to].add(_amount);

        Transfer(address(0), _to, _amount);
        return true;
    }
    
    /**
     * @dev Function to mint coins
     * @param _to The address that will receive the minted coins.
     * @param _amount The amount of coins to mint.
     * @param _note The notation for ethereum blockchain event log system
     * @return A boolean that indicates if the operation was successful.
     * @dev reference : https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/MintableToken.sol
     */
    function mint(address _to, uint256 _amount, string _note) onlyOwner public returns (bool) {
        require(mint(_to, _amount));
        KSC_Mint(_to, msg.sender, _amount, _note);
        return true;
    }

    /**
     * @dev Burns a specific amount of coins.
     * @param _to The address that will be burned the coins.
     * @param _amount The amount of coins to be burned.
     * @return A boolean that indicates if the operation was successful.
     * @dev reference : https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/BurnableToken.sol
     */
    function burn(address _to, uint256 _amount) onlyOwner internal returns (bool) {
        require(_to != address(0));
        require(_amount <= balances[msg.sender]);

        balances[_to]= balances[_to].sub(_amount);
        totalSupply_= totalSupply_.sub(_amount);
        
        return true;
    }
    
    /**
     * @dev Burns a specific amount of coins.
     * @param _to The address that will be burned the coins.
     * @param _amount The amount of coins to be burned.
     * @param _note The notation for ethereum blockchain event log system
     * @return A boolean that indicates if the operation was successful.
     * @dev reference : https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/ERC20/BurnableToken.sol
     */
    function burn(address _to, uint256 _amount, string _note) onlyOwner public returns (bool) {
        require(burn(_to, _amount));
        KSC_Burn(_to, msg.sender, _amount, _note);
        return true;
    }
    
    // for crowdsale
    /**
     * @dev Function which allows users to buy KStarCoin during the crowdsale period
     * @param _to The address that will receive the coins.
     * @param _value The amount of coins to sell.
     * @param _note The notation for ethereum blockchain event log system
     * @return A boolean that indicates if the operation was successful.
     */
    function sell(address _to, uint256 _value, string _note) onlyOwner public returns (bool) {
        require(crowdsaleRaised.add(_value) <= CROWDSALE_HARDCAP);
        require(mint(_to, _value));
        
        crowdsaleRaised= crowdsaleRaised.add(_value);
        KSC_Buy(_to, msg.sender, _value, _note);
        return true;
    }
    
    // for buyer with cryptocurrency other than ETH
    /**
     * @dev This function is occured when owner mint coins to users as they buy with cryptocurrency other than ETH.
     * @param _to The address that will receive the coins.
     * @param _value The amount of coins to mint.
     * @param _note The notation for ethereum blockchain event log system
     * @return A boolean that indicates if the operation was successful.
     */
    function mintToOtherCoinBuyer(address _to, uint256 _value, string _note) onlyOwner public returns (bool) {
        require(mint(_to, _value));
        KSC_BuyOtherCoin(_to, msg.sender, _value, _note);
        return true;
    }
  
    // for bounty program
    /**
     * @dev Function to reward influencers with KStarCoin
     * @param _to The address that will receive the coins.
     * @param _value The amount of coins to mint.
     * @param _note The notation for ethereum blockchain event log system
     * @return A boolean that indicates if the operation was successful.
     */
    function mintToInfluencer(address _to, uint256 _value, string _note) onlyOwner public returns (bool) {
        require(mint(_to, _value));
        KSC_GetAsInfluencer(_to, msg.sender, _value, _note);
        return true;
    }
    
    // for KSCPoint (KStarLive ecosystem point)
    /**
     * @dev Function to exchange KSCPoint to KStarCoin
     * @param _to The address that will receive the coins.
     * @param _value The amount of coins to mint.
     * @param _note The notation for ethereum blockchain event log system
     * @return A boolean that indicates if the operation was successful.
     */
    function exchangePointToCoin(address _to, uint256 _value, string _note) onlyOwner public returns (bool) {
        require(mint(_to, _value));
        KSC_ExchangePointToCoin(_to, msg.sender, _value, _note);
        return true;
    }
    
    // Event functions to log the notation for ethereum blockchain 
    // for initializing
    event KSC_Initialize(address indexed _src, address indexed _desc, uint256 _value, string _note);
    
    // for transfer()
    event KSC_Send(address indexed _src, address indexed _desc, uint256 _value, string _note);
    event KSC_Receive(address indexed _src, address indexed _desc, uint256 _value, string _note);
    
    // for approve(), increaseApproval(), decreaseApproval()
    event KSC_Approve(address indexed _src, address indexed _desc, uint256 _value, string _note);
    event KSC_ApprovalInc(address indexed _src, address indexed _desc, uint256 _value, string _note);
    event KSC_ApprovalDec(address indexed _src, address indexed _desc, uint256 _value, string _note);
    
    // for transferFrom()
    event KSC_SendTo(address indexed _src, address indexed _desc, uint256 _value, string _note);
    event KSC_ReceiveFrom(address indexed _src, address indexed _desc, uint256 _value, string _note);
    
    // for mint(), burn()
    event KSC_Mint(address indexed _src, address indexed _desc, uint256 _value, string _note);
    event KSC_Burn(address indexed _src, address indexed _desc, uint256 _value, string _note);
    
    // for crowdsale
    event KSC_Buy(address indexed _src, address indexed _desc, uint256 _value, string _note);
    
    // for buyer with cryptocurrency other than ETH
    event KSC_BuyOtherCoin(address indexed _src, address indexed _desc, uint256 _value, string _note);
    
    // for bounty program
    event KSC_GetAsInfluencer(address indexed _src, address indexed _desc, uint256 _value, string _note);

    // for KSCPoint (KStarLive ecosystem point)
    event KSC_ExchangePointToCoin(address indexed _src, address indexed _desc, uint256 _value, string _note);
}
/**
 * @title KStarCoinBasic
 */
function exchangePointToCoin(address _to, uint256 _value, string _note) onlyOwner public returns (bool) {
    require(mint(_to, _value));
    KSC_ExchangePointToCoin(_to, msg.sender, _value, _note);
    return true;
}

/**
 * @dev Function to exchange KSCPoint to KStarCoin
 * @param _to The address that will receive the coins.
 * @param _value The amount of coins to mint.
 * @param _note The notation for ethereum blockchain event log system
 * @return A boolean that indicates if the operation was successful.
 */