 
+# A class which implement collection interface.
+# You might use it as alternative standard javascript arrays.
+#
+# @example
+#
+#   class MyModel extends Sirius.BaseModel
+#     @attrs: ["id"]
+#
+#   myCollection = new Sirius.Collection(MyModel, [], {
+#     every: 1000,
+#     on_remove: () ->
+#       json = ... # ajax call
+#       return json
+#
+#     on_remove: (model) ->
+#       id = model.id
+#       #ajax call with id
+#
+#     on_add: (model) ->
+#       $('list-of-models').append(model.to_html())
+#
+#   })
+#
+#  myModel = new MyModel({"id" : 1}
+#  myCollection.add(myModel)
+#  myCollection.add(new MyModel({"id" : 2})
+#  myCollection.add(new MyModel({"id" : 3})
+#
+#  myCollection.index(myModel) # => 0
+#  myCollection.find("id", 1)  # => MyModel Instance
+#  myCollection.find("id", 1)  # => [ MyModel Instances ]
+#  myCollection.filter( (model) -> model.get("id") > 2 ) # => [ MyModel Instances ]
+#  myCollection.first() # => first MyModel instance
+#  myCollection.last()  # => last MyModel instance
+#
+#  myCollection.unsycn() # stop synchronization with server
+#  myCollection.sync(3000)   # start sync every 3 second
+#
 class Sirius.Collection
+  #
+  # @param klass [T <: Sirius.BaseModel] - model class for all instances in collection
+  # @param klasses [Array] - models, which used for `to_json` @see(Sirius.BaseModel.to_json)
+  # @param options [Object] - with keys necessary
+  # @param every [Numberic] - ms for remote call
+  # @param on_add [Function] - callback, which will be call when add new instance to collection
+  # @param on_rmeove [Function] - callback, which will be call when remove model from collection
+  # @param on_remote [Function] - callback, which will be call when synchronize collection, must be return json
   #remote - ajax calls, should return json for model
   #klass Model klass, must be extend BaseModel
   constructor: (klass, klasses = [], options = {every: 0, on_add: @on_add, on_remove: @on_remove, remote: null}) ->

    @_timer    = null
    _start_sync(every)

  @_start_sync: (every) ->
    if (every != 0)
      @_timer = setInterval(@remote, every)


  unsync: () ->
    if @_timer
      clearInterval(@_timer)

  sync: (every) ->
    @_start_sync(every)

  #check if is instance of BaseModel
  push: (model) ->
    type = model.constructor.name
    throw new Error("Require `#{@_type}`, but given `#{model.constructor.name}`") if @_type isnt type
    @_array.push(model) #maybe it's a hash ? because hash have a keys, and simple remove, but need a unique id
    @on_add(model)

  add: (model) ->
    @push(model)

  remove: (other) ->
    inx = index(other)
    if inx != null
      @_array.splice(inx, 1)

  index: (model) ->
    inx = null
    for model, i in @_array when model.compare(other)

        break
    inx

  #
  # find model by key with value
  # @param key [String] - attribute
  # @param value [Any] - actual value
  # @return [Model | null]
  find: (key, value) ->
    @findAll(key, value)[0] || null

  #
  # find all models by key with value
  # @param key [String] - attribute
  # @param value [Any] - actual value
  # @return [Array<Model>]
  findAll: (key, value) ->
    for model in @_array when model.get(key) == value then model

  #
  # filter collection with `fn`, which must return boolean
  # @param fn [Function]
  # @return [Array<Model>]
  filter: (fn = ->) ->
    for model in @_array when fn.call(null, model) then model

  #
  # Iterate over collection with function
  # @param fn [Function]
  each: (fn = ->) ->
    for model in @_array then fn.call(model)

  # return first element in collection
  # @return [Model]
  first: () ->
    @_array[0]

  # return last element in collection
  # @return [Model]
  last: () ->
    @_array[@_array.length - 1]

  # return actual collection
  # @return [Array<Model>]
  all: () ->
    @_array

  # @nodoc
  on_remove: (model) ->

  # @nodoc
  on_add: (model) ->


