contract BYBToken is UnboundedRegularToken {

    uint public totalSupply = 20*10**10;
    uint8 constant public decimals = 2;
    string constant public name = "Bitin Token";
    string constant public symbol = "BYB";
	address public owner;
	mapping (address => uint) public freezes;

	/* This notifies clients about the amount burnt */
    event Burn(address indexed from, uint value);
	
	/* This notifies clients about the amount frozen */
    event Freeze(address indexed from, uint value);
	
	/* This notifies clients about the amount unfrozen */
    event Unfreeze(address indexed from, uint value);
	
    function BYBToken() public {
        balances[msg.sender] = totalSupply;
		owner = msg.sender;
        emit Transfer(address(0), msg.sender, totalSupply);
    }
	
	function totalSupply() public constant returns (uint){
		return totalSupply;
	}
    
    function burn(uint _value) public returns (bool success) {
		if (balances[msg.sender] >= _value && totalSupply - _value <= totalSupply){
			balances[msg.sender] -= _value; 								// Subtract from the sender
            totalSupply -= _value;
			emit Burn(msg.sender, _value);
			return true;
		}else {
            return false;
        }    
    }
	
	function freeze(uint _value) public returns (bool success) {
		if (balances[msg.sender] >= _value &&
		freezes[msg.sender] + _value >= freezes[msg.sender]){
			balances[msg.sender] -= _value;   				// Subtract from the sender
			freezes[msg.sender] += _value;            		// Updates totalSupply
			emit Freeze(msg.sender, _value);
			return true;
		}else {
            return false;
        }  
    }
	
	function unfreeze(uint _value) public returns (bool success) {
        if (freezes[msg.sender] >= _value &&
		balances[msg.sender] + _value >= balances[msg.sender]){
			freezes[msg.sender] -= _value;
			balances[msg.sender] += _value;
			emit Unfreeze(msg.sender, _value);
			return true;
		}else {
            return false;
        } 
    }
	
	function transferAndCall(address _to, uint _value, bytes _extraData) public returns (bool success) {
		if(transfer(_to,_value)){
			TransferReceiver(_to).receiveTransfer(msg.sender, _value, this, _extraData); 
			return true; 
		}
		else {
            return false;
        } 
    }
	
	function approveAndCall(address _spender, uint _value, bytes _extraData) public returns (bool success) {
		if(approve(_spender,_value)){
			ApprovalReceiver(_spender).receiveApproval(msg.sender, _value, this, _extraData) ;
			return true; 
		}
		else {
            return false;
        }  
    }
	
	// transfer balance to owner
	function withdrawEther(uint amount) public {
		if(msg.sender == owner){
			owner.transfer(amount);
		}
	}
	
	// can accept ether
	function() public payable {
    }
}
function() public payable {
    }
// can accept ether