         #always return the current promise if resolving to prevent multiple requests being run for the same resource
         return buyer if buyer?.then?
         buyer = User.find(username).then (user)-> buyer = user
+      else
+        buyer = undefined
 
+    updateStateFromSearch = ->
+      resolveProducts()
+      resolveBuyer()
 
-    setSearch = (buy)->
-      search = $location.search()
-      search.buyer = buy.buyer.username
-      search.basket = "true"
-      for entry in buy.consistsOfProducts
-        search[entry.product.name] = entry.amount
-      search
-
-    setFromBuy = (buy)->
-      if $location.path() == '/buy'
-        emptyBasketAndRemoveBuyer()
-        $location.search(setSearch(buy)).replace()
-      else
-        $location.search(setSearch(buy)).path('/buy')
+    $rootScope.$on '$routeUpdate', updateStateFromSearch
+    updateStateFromSearch()
 
     #return api-object with methods/objects accessible from outside
     {


    entryPrice = (entry)-> (entry.amount * entry.product.price)
    entryPriceReducer = (sum, entry)-> sum + entryPrice(entry)

    price = (entry)->
      if entry?
        entryPrice(entry)
      else
        products.reduce(entryPriceReducer, 0.0)

    isBuyable = -> products.length > 0 && buyer

    entryByProductName = (entries, name)->
      return entry for entry in entries when entry.product.name == name
      null

    delayedAddProduct = (name, amount)->
      entry = {product: {name: name, id: name}, amount}
      products.push entry
      (product)-> entry.product = product

    INTEGER_REGEXP = /^\d+$/m
    validateAndParseInteger = (value)->
      parseInt(value) if INTEGER_REGEXP.test(value)

    resolveProducts = ->
      oldProducts = products
      products = []
      for own k, v of $location.search()
        continue unless (v = validateAndParseInteger(v))?
        #update amount or add a new product if non-existent
        entry = entryByProductName(oldProducts, k)
        if entry?
          entry.amount = v
          products.push entry
        else
          Product.find(k).then delayedAddProduct(k, v)

      products

    hasProducts = -> resolveProducts().length > 0

    resolveBuyer = ->
      username = $location.search().buyer

angular.module('kassa').service('BasketService', [
  '$http'
  '$location'
  '$rootScope'
  'UserService'
  'ProductService'
  ($http, $location, $rootScope, User, Product)->
    products = []
    buyer = null

