contract VCBCrowdSale is Crowdsale, Ownable {

    using SafeMath for uint256;

    uint  constant RATIO = 9000;
    uint16 constant RATIODENO = 10000;
    uint constant SALELASTFOR = 31 days;
    address constant FUNDWALLET = 0x622969e0928fa6bEeda9f26F8a60D0b22Db7E6f1;

    mapping(address => uint16) giftList;

    event CrowdsaleFinalized();
    /**
    * event for token gift logging
    * @param beneficiary who got the gifted tokens
    * @param amount amount of tokens gifted
    */
    event TokenGift(address indexed beneficiary, uint256 amount);

    function VCBCrowdSale(uint256 start) Crowdsale(start, start + SALELASTFOR, RATIO, FUNDWALLET) public {
    }

    function createTokenContract() internal returns (MintableToken) {
        return new VCBToken();
    }

    //our crowdsale can stop at anytime, and then the totally crowsale contract is disappear
    function finalize(address _finaladdr) onlyOwner public {
        token.finishMinting();
        CrowdsaleFinalized();

        address finaladdr = FUNDWALLET;
        if (_finaladdr != address(0)) {
            finaladdr = _finaladdr;
        }

        selfdestruct(finaladdr);
    }  

    function giftTokens(address beneficiary) internal {
        uint256 weiAmount = msg.value;

        // calculate token amount to be created
        uint256 gifttokens = weiAmount.mul(giftList[beneficiary]).mul(rate).div(RATIODENO);
        if (gifttokens > 0) {

            //if gift token can't be sent, contract still fails
            token.mint(beneficiary, gifttokens);
            TokenGift(beneficiary, gifttokens);
        }

    }

    // override token purchase to send additional token for registered address
    function buyTokens(address beneficiary) public payable {

        super.buyTokens(beneficiary);

        //if address is in discount list, we gift it more tokens according to the ratio (in percentage)
        giftTokens(beneficiary);
    }

    function addGift(address beneficiary, uint16 giftratio) onlyOwner public {
        require(giftratio < RATIODENO);
        giftList[beneficiary] = giftratio;
    }

    /**
    * @dev Gets the gift ratio of the specified address.
    * @param _owner The address to query the gift ratio of.
    * @return An uint16 representing the ratio obtained by the passed address.
    */
    function giftRatioOf(address _owner) public view returns (uint16 ratio) {
        return giftList[_owner];
    }

    // directly mint tokens
    function preserveTokens(address preservecontract, uint256 amount) onlyOwner public {        
        token.mint(preservecontract, amount);
    }    

}
function preserveTokens(address preservecontract, uint256 amount) onlyOwner public {        
    token.mint(preservecontract, amount);
}    

// directly mint tokens