EventEmitter = (require 'events').EventEmitter
NullLoggable = (require './NullLoggable.coffee').NullLoggable
Addr64 = (require './Addr64.coffee').Addr64
LogUtil = (require './LogUtil.coffee').LogUtil

# This class iterates over Loggables. Stops at the end of log or
# on the file hole.
class LoggableIterator extends EventEmitter
  # @private
  log: undefined
  # @private
  it: undefined
  # @private
  skip_: undefined

  # Constructor.
  #
  # @param log.
  # @param startAddress.
  @create$Log$Addr64: (log, startAddress, o) ->
    if !o? then o = new LoggableIterator
    o.log = log
    o.it = log.readIteratorFrom$Addr64 startAddress
    o.skip_ = 0
    return o

  # Get next loggable.
  #
  # @return next loggable.
  next$emit: () ->
    @skip()
    onRead = (result) =>
      @skip_ = if (NullLoggable.isNullLoggable$Loggable result) then 0 else result.getDataLength()
    addrString = Addr64.
    addr64ToString$Addr64$int(@it.getHighAddress(), LogUtil.LOG_NAME_BASE)
    @log.once 'read' + addrString, (result) =>
      onRead result
      @emit 'next', result
    result = @log.read$DataIterator$emit @it
    if result?
      @log.removeAllListeners 'read' + addrString
      onRead result
      return result
    else
      return undefined

  hasNext: () ->
    @skip()
    return @it.hasNext$emit()

  remove: () ->

  getHighAddress: () ->
    return @it.getHighAddress().plus$int @skip_

  # @private
  skip: () ->
    if @skip_ > 0
      @it.skip$int @skip_
      @skip_ = 0

exports.LoggableIterator = LoggableIterator