# todod module
# 1. create a socket
# 2. the socket parses and serialize data
# 3. the socket handles network errors

module.exports = {

	create-socket: (socket-url) ->
		self = {}

		request-types = {
			"list-lists":   0
			"get-list":     1
			"add-list":     2
			"edit-list":    3
			"remove-list":  4
			"get-tasks":    5
			"get-task":     6
			"add-task":     7
			"remove-task":  8
			"edit-task":    9
			"subscribe":   10
			"unsubscribe": 11
			"set-permission": 12
		}

		response-types = {
			"ok":            0
			"error":         1
			"lists-list":    2
			"new-list":      3
			"list-removed":  4
			"list-updated":  5
			"tasks":         6
			"task":          7
			"task-created":  8
			"task-removed":  9
			"task-updated": 10
			"subscribed":   11
			"unsubscribed": 12
		}

		# users can record functions to run on events
		self.user-on-socket-error = []
		self.user-on-socket-close = []

		self.callbacks = {}
		for key, value of response-types
			self.callbacks[value] = []

		self.add-event-listener = (type, callback) ->
			# console.log "add event listener", type, callback, response-types[type]
			type = response-types[type]

			self.callbacks[type] ++= [callback]

		self.open-socket = ->
			console.log "Opening socket to #{socket-url}"
			self.socket := new WebSocket socket-url

			self.socket.onerror = (event) ->
				for f in self.user-on-socket-error
					f event
				self.socket.close!

			self.socket.onclose = (event) ->
				for f in self.user-on-socket-close
					f event

			self.socket.onmessage = (event) ->
				message = JSON.parse(event.data)
				parsed-message = JSON.parse(message.payload)

				console.log "received todod message:", parsed-message

				for f in self.callbacks[message.mtype]
					f parsed-message

		self.reopen = ->
			self.socket.close!
			self.open-socket!

		self.open-socket!

		self.send = (type, opts) ->
			self.socket.send JSON.stringify { mtype: type, payload: opts }


		self.list-lists = ->
			self.send request-types[\list-lists], JSON.stringify {
				token: self.token
				id: "list-lists"
			}

		self.get-list = (list-id) ->
			self.send request-types[\get-list], JSON.stringify {
				token: self.token
				list: list-id
				id: "get-list"
			}

		self.get-tasks = (list-id) ->
			self.send request-types[\get-tasks], JSON.stringify {
				token: self.token
				list: list-id
				id: "get-tasks"
			}

		self.get-task = (task-id) ->
			self.send request-types[\get-task], JSON.stringify {
				token: self.token
				task: task-id
				id: "get-task"
			}

		self.remove-list = (list-id) ->
			self.send request-types[\remove-list], JSON.stringify {
				token: self.token
				list: list-id
				id: "remove-list"
			}

		# TODO: extra properties
		self.add-list = (title, opts) ->
			payload = {
				token: self.token
				title: title
				id: "add-list"
			}

			for key, value of opts
				payload[key] = value

			self.send request-types[\add-list], JSON.stringify payload

		self.edit-list = (list-id, opts) ->
			payload = {
				token: self.token
				list: list-id
				id: "edit-list"
			}

			for key, value of opts
				payload[key] = value

			self.send request-types[\edit-list], JSON.stringify payload

		self.remove-task = (task-id) ->
			self.send request-types[\remove-task], JSON.stringify {
				token: self.token
				task: task-id
				id: "remove-task"
			}

		# TODO: extra properties
		self.add-task = (list-id, title, opts) ->
			payload = {
				token: self.token
				list: list-id
				title: title
				id: "add-task"
			}

			for key, value of opts
				payload[key] = value

			self.send request-types[\add-task], JSON.stringify payload

		self.edit-task = (task-id, opts) ->
			payload = {
				token: self.token
				task: task-id
				id: "edit-task"
			}

			for key, value of opts
				payload[key] = value

			self.send request-types[\edit-task], JSON.stringify payload

		self.subscribe = (list-id) ->
			self.send request-types[\subscribe], JSON.stringify {
				token: self.token
				list: list-id
				id: "subscribe"
			}

		self.unsubscribe = (list-id) ->
			self.send request-types[\unsubscribe], JSON.stringify {
				token: self.token
				list: list-id
				id: "unsubscribe"
			}

		self
}
