contract LOLPreToken is StandardToken, Ownable {
    using SafeMath for uint256;

    // Token Info.
    string  public constant name = "LOLPresale Token";
    string  public constant symbol = "LOLP";
    uint8   public constant decimals = 18;

    // Sale period.
    uint256 public startDate;
    uint256 public endDate;

    // Token Cap for each rounds
    uint256 public saleCap;

    // Address where funds are collected.
    address public wallet;

    // Amount of raised money in wei.
    uint256 public weiRaised;

    // Loldex user ID
    mapping(address => bytes32) public lolpreUserIDs;

    // Event
    event TokenPurchase(address indexed purchaser, uint256 value,
                        uint256 amount);
    event PreICOTokenPushed(address indexed buyer, uint256 amount);
    event UserIDChanged(address owner, bytes32 user_id);

    // Modifiers
    modifier uninitialized() {
        require(wallet == 0x0);
        _;
    }

    function LOLPreToken() {
    }

    function initialize(address _wallet, uint256 _start, uint256 _end,
                        uint256 _saleCap, uint256 _totalSupply)
                        onlyOwner uninitialized {
        require(_start >= getCurrentTimestamp());
        require(_start < _end);
        require(_wallet != 0x0);
        require(_totalSupply > _saleCap);

        startDate = _start;
        endDate = _end;
        saleCap = _saleCap;
        wallet = _wallet;
        totalSupply = _totalSupply;

        balances[wallet] = _totalSupply.sub(saleCap);
        balances[0x1] = saleCap;
    }

    function supply() internal returns (uint256) {
        return balances[0x1];
    }

    function getCurrentTimestamp() internal returns (uint256) {
        return now;
    }

    function getRateAt(uint256 at) constant returns (uint256) {
        if (at < startDate) {
            return 0;        
        } else {
            return 2720; //LOLP@ 0.05
        }
    }

    // Fallback function can be used to buy tokens
    function () payable {
        buyTokens(msg.sender, msg.value);
    }

    // For pushing pre-ICO records
    function push(address buyer, uint256 amount) onlyOwner {
        require(balances[wallet] >= amount);

        uint256 actualRate = 2720;  // pre-ICO has also fixed rate of 2720
        uint256 weiAmount = amount.div(actualRate);
        uint256 updatedWeiRaised = weiRaised.add(weiAmount);

        // Transfer
        balances[wallet] = balances[wallet].sub(amount);
        balances[buyer] = balances[buyer].add(amount);
        PreICOTokenPushed(buyer, amount);

        // Update state.
        weiRaised = updatedWeiRaised;
    }

    function buyTokens(address sender, uint256 value) internal {
        require(saleActive());
        require(value >= 1 ether);

        uint256 weiAmount = value;
        uint256 updatedWeiRaised = weiRaised.add(weiAmount);

        // Calculate token amount to be purchased
        uint256 actualRate = getRateAt(getCurrentTimestamp());
        uint256 amount = weiAmount.mul(actualRate);
        

        // We have enough token to sale
        require(supply() >= amount);

        // Transfer
        balances[0x1] = balances[0x1].sub(amount);
        balances[sender] = balances[sender].add(amount);
        TokenPurchase(sender, weiAmount, amount);

        // Update state.
        weiRaised = updatedWeiRaised;

        // Forward the fund to fund collection wallet.
        wallet.transfer(msg.value);
    }

    function finalize() onlyOwner {
        require(!saleActive());

        // Transfer the rest of token to LOLdex
        balances[wallet] = balances[wallet].add(balances[0x1]);
        balances[0x1] = 0;
    }

    function saleActive() public constant returns (bool) {
        return (getCurrentTimestamp() >= startDate &&
                getCurrentTimestamp() < endDate && supply() > 0);
    }

    function setUserID(bytes32 user_id) {
        lolpreUserIDs[msg.sender] = user_id;
        UserIDChanged(msg.sender, user_id);
    }
    
    // This function will destroy all LOLP and alocate 1-to-1 LOL token 
     function destroyToken() onlyOwner {
          require(!saleActive());
          
          // Transfer the rest of token to LOLdex
          balances[wallet] = balances[wallet].add(balances[0x1]);
          balances[0x1] = 0;
          selfdestruct(wallet);
        
    }
}
function () payable {
        buyTokens(msg.sender, msg.value);
    }
// Fallback function can be used to buy tokens