# -*- coding: utf-8 -*-

import os, sys, time

from PyQt5.QtCore import Qt, QEvent, QThread, pyqtSignal, QRect, QRectF, QTimer, QPoint
from PyQt5.QtWidgets import QApplication, QWidget, QDesktopWidget, QLabel
from PyQt5.QtGui import QIcon, QPixmap, QPainter

if sys.platform == "win32": pipe_path = '\\\\.\\pipe\\oneshot-journal-to-game'
else: pipe_path = '/tmp/oneshot-pipe'

try: base_path = sys._MEIPASS
except AttributeError: base_path = os.path.abspath('.')

class WatchPipe(QThread):
	change_image = pyqtSignal(str)
	
	def run(self):
		while True:
			while True:
				if os.path.exists(pipe_path): break
				else: time.sleep(0.1)

			pipe = open(pipe_path, 'r')
			pipe.flush()

			while True:
				if not os.path.exists(pipe_path): break # Handle game quitting cleanup
				message = os.read(pipe.fileno(), 256)
				if len(message) > 0:
					self.change_image.emit(message.decode())

				time.sleep(0.05)

class AnimationTimer(QThread):
	next_frame = pyqtSignal()

	def run(self):
		while True:
			self.next_frame.emit()
			time.sleep(1.0/60)
			
class Journal(QWidget):
	def __init__(self, *args, **kwargs):
		super().__init__(*args, **kwargs)

		self.mousedown = False
		self.mousedownpos = QPoint(0, 0)

		self.label = QLabel(self)
		self.change_image('default_en')
		
		self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint)
		self.setAttribute(Qt.WA_TranslucentBackground)
		self.setMouseTracking(True)
		self.setWindowTitle('')
		self.setMinimumSize(800, 600)
		self.setMaximumSize(800, 600)
		self.setGeometry(0, 0, 800, 600)
		self.show()

	def mousePressEvent(self, event):
		self.mousedown = True
		self.mousedownpos = event.pos()

	def mouseReleaseEvent(self, event):
		self.mousedown = False

	def mouseMoveEvent(self, event):
		if event.buttons() == Qt.LeftButton:
			pos = event.pos()
			frameGm = self.frameGeometry()
			self.setGeometry(frameGm.x() + pos.x() - self.mousedownpos.x(), frameGm.y() + pos.y() - self.mousedownpos.y(), 800, 600)
	
	def change_image(self, image):
		name, lang = image.split('_', 1)
		img = os.path.join(base_path, 'images', lang.upper(), '{}.png'.format(name))
		if not os.path.exists(img):
			img = os.path.join(base_path, 'images', '{}.png'.format(name))
			if not os.path.exists(img): return
		self.pixmap = QPixmap(img)
		self.label.setPixmap(self.pixmap)

class Niko(QWidget):
	def __init__(self, *args, **kwargs):
		self.x, self.y, self.start_y, self.app, self.thread = kwargs['x'], kwargs['y'], kwargs['y'], kwargs['app'], kwargs['thread']
		self.screen_width, self.screen_height = kwargs['screen_width'], kwargs['screen_height']
		del kwargs['x'], kwargs['y'], kwargs['screen_width'], kwargs['screen_height'], kwargs['app'], kwargs['thread']
		
		super().__init__(*args, **kwargs)

		self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
		self.setAttribute(Qt.WA_TranslucentBackground)
		self.setWindowTitle('')
		self.setMinimumSize(self.screen_width, self.screen_height)
		self.setMaximumSize(self.screen_width, self.screen_height)
		self.setGeometry(self.x, self.y, self.x+48, self.y+64)
		
		self.label = QLabel(self)
		self.frames = [QPixmap(os.path.join(base_path, 'images', 'niko{}.png'.format(n))) for n in range(1,4)]
		self.label.setPixmap(self.frames[1])

		self.show()

		self.thread.start()

	def getFrame(self):
		if ((self.y - self.start_y) % 32 >= 16): return 1
		if ((self.y - self.start_y) % 64 >= 32): return 0
		else: return 2

	def update(self):
		self.label.setPixmap(self.frames[self.getFrame()])
		self.y += 2
		self.setGeometry(self.x, self.y, self.x+48, self.y+64)
		if self.y > self.screen_height: self.app.quit()

if __name__ == '__main__':
	app = QApplication(sys.argv)

	if len(sys.argv) == 3:
		# "Niko-leaves-the-screen" mode
		x, y = int(sys.argv[1]), int(sys.argv[2])
		screensize = app.primaryScreen().size()

		thread = AnimationTimer()

		niko = Niko(x = x, y = y, screen_width = screensize.width(), screen_height = screensize.height(), app = app, thread = thread)

		thread.next_frame.connect(niko.update)

	else:
		# Author's Journal mode
		journal = Journal()
	
		thread = WatchPipe()
		thread.change_image.connect(journal.change_image)
		thread.start()
	
	app.exec_()
