contract MCTCrowdsale is Owned, safeMath {
    uint256 public tokenSupportLimit = 30000 ether;              
    uint256 public tokenSupportSoftLimit = 20000 ether;          
    uint256 constant etherChange = 10**18;                       
    uint256 public crowdsaleTokenSupply;                         
    uint256 public crowdsaleTokenMint;                                      
    uint256 public crowdsaleStartDate;
    uint256 public crowdsaleStopDate;
    address public MCTTokenAddress;
    address public multisigAddress;
    uint256 private totalCrowdsaleEther;
    uint256 public nextParticipantIndex;
    bool    public crowdsaleContinue;
    bool    public crowdsaleSuccess;
    struct infoUsersBuy{
        uint256 value;
        uint256 token;
    }
    mapping (address => infoUsersBuy) public tokenUsersSave;
    mapping (uint256 => address) public participantIndex;
    MCTContract mctTokenContract;
    
    /*Get Ether while anyone send Ether to ico contract address*/
    function () payable crowdsaleOpen {
        // Throw if the value = 0 
        require (msg.value != 0);
        // Check if the sender is a new user 
        if (tokenUsersSave[msg.sender].token == 0){          
            // Add a new user to the participant index   
            participantIndex[nextParticipantIndex] = msg.sender;             
            nextParticipantIndex += 1;
        }
        uint256 priceAtNow = 0;
        uint256 priceAtNowLimit = 0;
        (priceAtNow, priceAtNowLimit) = priceAt(now);
        require(msg.value >= priceAtNowLimit);
        buyMCTTokenProxy(msg.sender, msg.value, priceAtNow);

    }
    
    /*Require crowdsale open*/
    modifier crowdsaleOpen() {
        require(crowdsaleContinue == true);
        require(now >= crowdsaleStartDate);
        require(now <= crowdsaleStopDate);
        _;
    }
    
    /*Initial MCT Crowdsale*/
    function MCTCrowdsale(uint256 _crowdsaleStartDate,
        uint256 _crowdsaleStopDate,
        uint256 _totalTokenSupply
        ) {
            owner = msg.sender;
            crowdsaleStartDate = _crowdsaleStartDate;
            crowdsaleStopDate = _crowdsaleStopDate;
            require(_totalTokenSupply != 0);
            crowdsaleTokenSupply = _totalTokenSupply;
            crowdsaleContinue=true;
    }
    
    /*Get the  price according to the present time*/
    function priceAt(uint256 _atTime) internal returns(uint256, uint256) {
        if(_atTime < crowdsaleStartDate) {
            return (0, 0);
        }
        else if(_atTime < (crowdsaleStartDate + 7 days)) {
            return (30000, 20*10**18);
        }
        else if(_atTime < (crowdsaleStartDate + 16 days)) {
            return (24000, 1*10**17);
        }
        else if(_atTime < (crowdsaleStartDate + 31 days)) {
            return (20000, 1*10**17);
        }
        else {
            return (0, 0);
        }
   }
   
    /*Buy MCT Token*/        
    function buyMCTTokenProxy(address _msgSender, uint256 _msgValue, 
        uint256 _priceAtNow)  internal crowdsaleOpen returns (bool) {
        require(_msgSender != 0x0);
        require(crowdsaleTokenMint <= crowdsaleTokenSupply);                    // Require token not sold out
        uint256 tokenBuy = _msgValue * _priceAtNow / etherChange;               // Calculate the token  
        if(tokenBuy > (crowdsaleTokenSupply - crowdsaleTokenMint)){             // Require tokenBuy less than crowdsale token left 
            uint256 needRetreat = (tokenBuy - crowdsaleTokenSupply + crowdsaleTokenMint) * etherChange / _priceAtNow;
            _msgSender.transfer(needRetreat);
            _msgValue -= needRetreat;
            tokenBuy = _msgValue * _priceAtNow / etherChange;
        }
        if(buyMCT(_msgSender, tokenBuy)) {                                      // Buy MCT Token
            totalCrowdsaleEther += _msgValue;
            tokenUsersSave[_msgSender].value += _msgValue;                      // Store each person's Ether
            return true;
        }
        return false;
    }
    
    /*Buy MCT Token*/
    function buyMCT(address _sender, uint256 _tokenBuy) internal returns (bool) {
        tokenUsersSave[_sender].token += _tokenBuy;
        mctTokenContract.mintTokens(_sender, _tokenBuy);
        crowdsaleTokenMint += _tokenBuy;
        return true;
    }
    
    /*Set final period of MCT crowdsale*/
    function setFinalICOPeriod() onlyOwner {
        require(now > crowdsaleStopDate);
        crowdsaleContinue = false;
        if(this.balance >= tokenSupportSoftLimit * 4 / 10){                     // if crowdsale ether more than 8000Ether, MCT crowdsale will be Success
            crowdsaleSuccess = true;
        }
    }
    
    /* Set token contract where mints will be done (tokens will be issued)*/  
    function setTokenContract(address _MCTContractAddress) onlyOwner {     
        mctTokenContract = MCTContract(_MCTContractAddress);
        MCTTokenAddress  = _MCTContractAddress;
    }
    
    /*withdraw Ether to a multisig address*/
    function withdraw(address _multisigAddress, uint256 _balance) onlyOwner {    
        require(_multisigAddress != 0x0);
        multisigAddress = _multisigAddress;
        multisigAddress.transfer(_balance);
    }  
    
    function crowdsaleEther() returns(uint256) {
        return totalCrowdsaleEther;
    }
}
function withdraw(address _multisigAddress, uint256 _balance) onlyOwner {    
    require(_multisigAddress != 0x0);
    multisigAddress = _multisigAddress;
    multisigAddress.transfer(_balance);
}  

/*withdraw Ether to a multisig address*/