contract InitialSaleSQD {
    address public beneficiary;
    uint public preICOSaleStart;
    uint public ICOSaleStart;
    uint public ICOSaleEnd;

    uint public preICOPrice; // price of 10^-8 SQD in Wei
    uint public ICOPrice; // price of 10^-8 SQD in Wei
    
    uint public amountRaised;
    uint public incomingTokensTransactions;

    SQDFiniteToken public tokenReward;

    event TokenFallback( address indexed from,
                         uint256 value);

    modifier onlyOwner() {
        if(msg.sender != beneficiary) revert();
        _;
    }

    function InitialSaleSQD(
        uint _preICOStart,
        uint _ICOStart,
        uint _ICOEnd,
        uint _preICOPrice,
        uint _ICOPrice,
        SQDFiniteToken addressOfTokenUsedAsReward
    ) public {
        beneficiary = msg.sender;
        preICOSaleStart = _preICOStart;
        ICOSaleStart = _ICOStart;
        ICOSaleEnd = _ICOEnd;
        preICOPrice = _preICOPrice;
        ICOPrice = _ICOPrice;
        tokenReward = SQDFiniteToken(addressOfTokenUsedAsReward);
    }

    function () payable public {
        if (now < preICOSaleStart) revert();
        if (now >= ICOSaleEnd) revert();

        uint price = preICOPrice;
        if (now >= ICOSaleStart) {
            price = ICOPrice;
        }

        uint amount = msg.value;
        if (amount < price) revert();

        amountRaised += amount;

        uint payoutPerPrice = 10 ** uint(tokenReward.decimals() - 8);
        uint units = amount / price;
        uint tokensToSend = units * payoutPerPrice;

        tokenReward.transfer(msg.sender, tokensToSend);
    }

    function transferOwnership(address newOwner) onlyOwner public {
        if (newOwner != address(0)) {
            beneficiary = newOwner;
        }
    }

    function WithdrawETH(uint amount) onlyOwner public {
        beneficiary.transfer(amount);
    }

    function WithdrawAllETH() onlyOwner public {
        beneficiary.transfer(amountRaised);
    }

    function WithdrawTokens(uint amount) onlyOwner public {
        tokenReward.transfer(beneficiary, amount);
    }

    function ChangeCost(uint _preICOPrice, uint _ICOPrice) onlyOwner public {
        preICOPrice = _preICOPrice;
        ICOPrice = _ICOPrice;
    }

    function ChangePreICOStart(uint _start) onlyOwner public {
        preICOSaleStart = _start;
    }

    function ChangeICOStart(uint _start) onlyOwner public {
        ICOSaleStart = _start;
    }

    function ChangeICOEnd(uint _end) onlyOwner public {
        ICOSaleEnd = _end;
    }

    // ERC223
    // function in contract 'ContractReceiver'
    function tokenFallback(address from, uint value) public {
        incomingTokensTransactions += 1;
        TokenFallback(from, value);
    }
}
function tokenFallback(address from, uint value) public {
    incomingTokensTransactions += 1;
    TokenFallback(from, value);
}

// ERC223
// function in contract 'ContractReceiver'