class StatusNetMeego(dbus.service.Object):


	def __init__(self):
		self.app = QtGui.QApplication(sys.argv)
		self.app.setApplicationName("StatusNet")
		signal.signal(signal.SIGINT, signal.SIG_DFL)

		self.signals = Signals()

		self.statuses = {}
		self.favourites = {}
		self.replyingTo = None

		self.client = gconf.client_get_default()
		self.api_path = self.client.get_string('/apps/ControlPanel/Statusnet/api_path')
		if not self.api_path:
			ret = subprocess.call(["/usr/bin/invoker", "--type=e", "-s", "/opt/statusnet-meego/statusnet-login.py"])
			if ret == 2:
				self.api_path = self.client.get_string('/apps/ControlPanel/Statusnet/api_path')
			else:
				# Quit if the user just closed the configuration applet without setting up login details
				return

		self.login()

		self.cacheDir = QtGui.QDesktopServices.storageLocation(QtGui.QDesktopServices.CacheLocation)
		if not os.path.exists(self.cacheDir):
			os.mkdir(self.cacheDir)
		self.timelineModel = TimelineModel()
		self.signals.onAddStatus.connect(self.addStatus)
		self.signals.onDoneWorking.connect(self.doneWorking)
		self.signals.onDoneSending.connect(self.doneSending)
		self.signals.onDoneMessage.connect(self.doneMessage)
		self.signals.onDoneFavourite.connect(self.doneFavourite)
		self.signals.onUpdateFollowing.connect(self.updateFollowing)
		self.signals.onError.connect(self.error)
		self.view = QtDeclarative.QDeclarativeView()
		self.view.setSource("/opt/statusnet-meego/qml/Main.qml")
		self.rootObject = self.view.rootObject()
		self.context = self.view.rootContext()
		self.context.setContextProperty('timelineModel', self.timelineModel)
		self.rootObject.openFile("TimelinePage.qml")
		self.rootObject.send.connect(self.send)
		self.rootObject.back.connect(self.back)
		self.rootObject.refresh.connect(self.updateTimeline)
		self.rootObject.fetchMore.connect(self.fetchMore)
		self.rootObject.selectMessage.connect(self.showStatus)
		self.rootObject.linkClicked.connect(self.openLink)
		self.rootObject.favourite.connect(self.favourite)
		self.rootObject.unfavourite.connect(self.unfavourite)
		self.rootObject.follow.connect(self.follow)
		self.rootObject.unfollow.connect(self.unfollow)
		self.rootObject.repeat.connect(self.repeat)
		self.view.showFullScreen()
		self.latest = -1
		self.earliest = None
		self.updateTimeline()
		# Update every 10 minutes
		timer = QtCore.QTimer(self.signals)
		timer.timeout.connect(self.updateTimeline)
		timer.start(600000)
		dbus_main_loop = dbus.glib.DBusGMainLoop(set_as_default=True)
		session_bus = dbus.SessionBus(dbus_main_loop)
		bus_name = dbus.service.BusName("com.mikeasoft.statusnet.eventcallback", bus=session_bus)
	        dbus.service.Object.__init__(self, object_path="/EventFeedService", bus_name=bus_name)

		sys.exit(self.app.exec_())


	def login(self):
		try:
			if self.api_path in oauth_consumer_keys:
				key = oauth_consumer_keys[self.api_path]
				secret = oauth_consumer_secrets[self.api_path]
				oauth_token = self.client.get_string("/apps/ControlPanel/Statusnet/oauth_token")
				oauth_token_secret = self.client.get_string("/apps/ControlPanel/Statusnet/oauth_token_secret")
				self.statusNet = StatusNet(self.api_path, auth_type="oauth", consumer_key=key, consumer_secret=secret, oauth_token=oauth_token, oauth_token_secret=oauth_token_secret)
			else:
				username = self.client.get_string('/apps/ControlPanel/Statusnet/username')
				password= self.client.get_string('/apps/ControlPanel/Statusnet/password')
				self.statusNet = StatusNet(self.api_path, username, password)
		except:
			ret = subprocess.call(["/usr/bin/invoker", "--type=e", "-s", "/opt/statusnet-meego/statusnet-login.py"])
			if ret == 2:
				self.login()
			else:
				return


	def updateTimeline(self):
		self.rootObject.startWorking()
		thread = threading.Thread(target=self._updateTimeline)
		thread.start()


	def _updateTimeline(self):
		statuses = self.statusNet.statuses_home_timeline(self.latest)
		if len(statuses) > 0:
			self.latest = statuses[0]['id']
			if self.earliest == None or self.earliest > statuses[-1]['id']:
				self.earliest = statuses[-1]['id']
			statuses.reverse()
			for status in statuses:
				self.signals.onAddStatus.emit(status, self.timelineModel, False)
		self.signals.onDoneWorking.emit()


	def fetchMore(self):
		self.rootObject.startWorking()
		thread = threading.Thread(target=self._fetchMore)
		thread.start()


	def _fetchMore(self):
		statuses = self.statusNet.statuses_home_timeline(max_id=self.earliest-1, count=20)
		if len(statuses) > 0:
			if self.earliest == None or self.earliest > statuses[-1]['id']:
				self.earliest = statuses[-1]['id']
			for status in statuses:
				self.signals.onAddStatus.emit(status, self.timelineModel, True)
		self.signals.onDoneWorking.emit()


	def doneWorking(self):
		self.rootObject.stopWorking()


	def addStatus(self, status, model, addToEnd=False):
		self.statuses[status['id']] = status
		icon = statusnetutils.getAvatar(status['user']['profile_image_url'], self.cacheDir)
		creationtime = statusnetutils.getTime(status['created_at'])
		html = status['statusnet_html'].replace("<a ", "<a style='color: #a0a0a0;' ")
		html = html.replace("&quot;", '"')
		status = Status(status['user']['name'], html, icon, status['id'], status['statusnet_conversation_id'], creationtime.strftime("%c"), status['favorited'], status['user']['following'], status['user']['id'])
		if addToEnd:
			model.addToEnd(status)
		else:
			model.add(status)


	def showStatus(self, statusid, conversationid):
		self.rootObject.startWorking()
		self.replyingTo = statusid
		self.conversation = conversationid
		try:
			status = self.statuses[statusid]
		except:
			status = self.statusNet.statuses_show(statusid)
		self.rootObject.setStatusPlaceholder("Reply to %s..." % status['user']['name'])
		conversationModel = TimelineModel()
		self.context.setContextProperty('timelineModel', conversationModel)
		thread = threading.Thread(target=self._showStatus, args=(status, conversationid, conversationModel))
		thread.start()


	def _showStatus(self, status, conversationid, conversationModel):
		conversation = self.statusNet.statusnet_conversation(conversationid)
		for status in conversation:
			self.signals.onAddStatus.emit(status, conversationModel, False)
		self.signals.onDoneWorking.emit()

	
	def back(self):
		self.replyingTo = None
		self.conversation = None
		self.rootObject.setStatusPlaceholder("Update your status...")
		self.context.setContextProperty('timelineModel', self.timelineModel)


	def send(self, status):
		self.rootObject.startWorking()
		thread = threading.Thread(target=self._send, args=(status.encode("utf-8"),))
		thread.start()


	def _send(self, status):
		try:
			if self.replyingTo:
				self.statusNet.statuses_update(status, in_reply_to_status_id=self.replyingTo)
			else:
				self.statusNet.statuses_update(status)
			self.signals.onDoneSending.emit()
		except Exception, err:
			self.signals.onError.emit("Problem sending message", err.message)
			self.signals.onDoneWorking.emit()