contract Pausable is Ownable {

  // timestamps until all tokens transfers are blocked
  uint256 public blockedTimeForBountyTokens = 0;
  uint256 public blockedTimeForInvestedTokens = 0;

  // minimum timestamp that tokens will be blocked for transfers
  uint256 constant MIN_blockedTimeForBountyTokens = 1524949200; //29.04.2018, 0:00:00
  uint256 constant MIN_blockedTimeForInvestedTokens = 1521061200; //15.03.2018, 0:00:00

  //Addresses pre-ico investors
  mapping(address => bool) preIcoAccounts;

  //Addresses bounty campaign
  mapping(address => bool) bountyAccounts;

  //Addresses with founders tokens and flag is it blocking transfers from this address
  mapping(address => uint) founderAccounts; // 1 - block transfers, 2 - do not block transfers

  function Pausable() public {
    blockedTimeForBountyTokens = MIN_blockedTimeForBountyTokens;
    blockedTimeForInvestedTokens = MIN_blockedTimeForInvestedTokens;
  }

  /**
  * @dev called by owner for changing blockedTimeForBountyTokens
  */
  function changeBlockedTimeForBountyTokens(uint256 _blockedTime) onlyOwner external {
    require(_blockedTime < MIN_blockedTimeForBountyTokens);
    blockedTimeForBountyTokens = _blockedTime;
  }

  /**
* @dev called by owner for changing blockedTimeForInvestedTokens
*/
  function changeBlockedTimeForInvestedTokens(uint256 _blockedTime) onlyOwner external {
    require(_blockedTime < MIN_blockedTimeForInvestedTokens);
    blockedTimeForInvestedTokens = _blockedTime;
  }


  /**
   * @dev Modifier to make a function callable only when the contract is not paused.
   */
  modifier whenNotPaused() {
    require(!getPaused());
    _;
  }

  /**
   * @dev Modifier to make a function callable only when the contract is paused.
   */
  modifier whenPaused() {
    require(getPaused());
    _;
  }

  function getPaused() internal returns (bool) {
    if (now > blockedTimeForBountyTokens && now > blockedTimeForInvestedTokens) {
      return false;
    } else {
      uint256 blockedTime = checkTimeForTransfer(msg.sender);
      return now < blockedTime;
    }
  }


  /**
  * @dev called by owner, add preIcoAccount
  */
  function addPreIcoAccounts(address _addr) onlyOwner internal {
    require(_addr != 0x0);
    preIcoAccounts[_addr] = true;
  }

  /**
  * @dev called by owner, add addBountyAccount
  */
  function addBountyAccounts(address _addr) onlyOwner internal {
    require(_addr != 0x0);
    preIcoAccounts[_addr] = true;
  }

  /**
  * @dev called by owner, add founderAccount
  */
  function addFounderAccounts(address _addr, uint _flag) onlyOwner external {
    require(_addr != 0x0);
    founderAccounts[_addr] = _flag;
  }

  /**
   * @dev called by external contract (ImmlaToken) for checking rights for transfers, depends on who owner of this address
   */
  function checkTimeForTransfer(address _account) internal returns (uint256) {
    if (founderAccounts[_account] == 1) {
      return blockedTimeForInvestedTokens;
    } else if(founderAccounts[_account] == 2) {
      return 1; //do not block transfers
    } else if (preIcoAccounts[_account]) {
      return blockedTimeForInvestedTokens;
    } else if (bountyAccounts[_account]) {
      return blockedTimeForBountyTokens;
    } else {
      return blockedTimeForInvestedTokens;
    }
  }
}
/**
 * @title Pausable
 * @dev Base contract which allows children to implement an emergency stop mechanism.
 */
function Pausable() public {
    blockedTimeForBountyTokens = MIN_blockedTimeForBountyTokens;
    blockedTimeForInvestedTokens = MIN_blockedTimeForInvestedTokens;
  }
// 1 - block transfers, 2 - do not block transfers