from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import *

_accessstrings = {0: "", 1: "readonly", 2: "executeonly", 3: "noaccess"}


class ps_object(object):

	literal = 1
	access = 0
	value = None

	def __init__(self, value):
		self.value = value
		self.type = self.__class__.__name__[3:] + "type"

	def __repr__(self):
		return "<%s %s>" % (self.__class__.__name__[3:], repr(self.value))


class ps_operator(ps_object):

	literal = 0

	def __init__(self, name, function):
		self.name = name
		self.function = function
		self.type = self.__class__.__name__[3:] + "type"
	def __repr__(self):
		return "<operator %s>" % self.name

class ps_procedure(ps_object):
	literal = 0
	def __repr__(self):
		return "<procedure>"
	def __str__(self):
		psstring = '{'
		for i in range(len(self.value)):
			if i:
				psstring = psstring + ' ' + str(self.value[i])
			else:
				psstring = psstring + str(self.value[i])
		return psstring + '}'

class ps_name(ps_object):
	literal = 0
	def __str__(self):
		if self.literal:
			return '/' + self.value
		else:
			return self.value

class ps_literal(ps_object):
	def __str__(self):
		return '/' + self.value

class ps_array(ps_object):
	def __str__(self):
		psstring = '['
		for i in range(len(self.value)):
			item = self.value[i]
			access = _accessstrings[item.access]
			if access:
				access = ' ' + access
			if i:
				psstring = psstring + ' ' + str(item) + access
			else:
				psstring = psstring + str(item) + access
		return psstring + ']'
	def __repr__(self):
		return "<array>"

_type1_pre_eexec_order = [
		"FontInfo",
		"FontName",
		"Encoding",
		"PaintType",
		"FontType",
		"FontMatrix",
		"FontBBox",
		"UniqueID",
		"Metrics",
		"StrokeWidth"
	]

_type1_fontinfo_order = [
		"version",
		"Notice",
		"FullName",
		"FamilyName",
		"Weight",
		"ItalicAngle",
		"isFixedPitch",
		"UnderlinePosition",
		"UnderlineThickness"
	]

_type1_post_eexec_order = [
		"Private",
		"CharStrings",
		"FID"
	]

def _type1_item_repr(key, value):
	psstring = ""
	access = _accessstrings[value.access]
	if access:
		access = access + ' '
	if key == 'CharStrings':
		psstring = psstring + "/%s %s def\n" % (key, _type1_CharString_repr(value.value))
	elif key == 'Encoding':
		psstring = psstring + _type1_Encoding_repr(value, access)
	else:
		psstring = psstring + "/%s %s %sdef\n" % (str(key), str(value), access)
	return psstring

def _type1_Encoding_repr(encoding, access):
	encoding = encoding.value
	psstring = "/Encoding 256 array\n0 1 255 {1 index exch /.notdef put} for\n"
	for i in range(256):
		name = encoding[i].value
		if name != '.notdef':
			psstring = psstring + "dup %d /%s put\n" % (i, name)
	return psstring + access + "def\n"

def _type1_CharString_repr(charstrings):
	items = sorted(charstrings.items())
	return 'xxx'

class ps_font(ps_object):
	def __str__(self):
		psstring = "%d dict dup begin\n" % len(self.value)
		for key in _type1_pre_eexec_order:
			try:
				value = self.value[key]
			except KeyError:
				pass
			else:
				psstring = psstring + _type1_item_repr(key, value)
		items = sorted(self.value.items())
		for key, value in items:
			if key not in _type1_pre_eexec_order + _type1_post_eexec_order:
				psstring = psstring + _type1_item_repr(key, value)
		psstring = psstring + "currentdict end\ncurrentfile eexec\ndup "
		for key in _type1_post_eexec_order:
			try:
				value = self.value[key]
			except KeyError:
				pass
			else:
				psstring = psstring + _type1_item_repr(key, value)
		return psstring + 'dup/FontName get exch definefont pop\nmark currentfile closefile\n' + \
				8 * (64 * '0' + '\n') + 'cleartomark' + '\n'
	def __repr__(self):
		return '<font>'

class ps_file(ps_object):
	pass

class ps_dict(ps_object):
	def __str__(self):
		psstring = "%d dict dup begin\n" % len(self.value)
		items = sorted(self.value.items())
		for key, value in items:
			access = _accessstrings[value.access]
			if access:
				access = access + ' '
			psstring = psstring + "/%s %s %sdef\n" % (str(key), str(value), access)
		return psstring + 'end '
	def __repr__(self):
		return "<dict>"

class ps_mark(ps_object):
	def __init__(self):
		self.value = 'mark'
		self.type = self.__class__.__name__[3:] + "type"

class ps_procmark(ps_object):
	def __init__(self):
		self.value = 'procmark'
		self.type = self.__class__.__name__[3:] + "type"

class ps_null(ps_object):
	def __init__(self):
		self.type = self.__class__.__name__[3:] + "type"

class ps_boolean(ps_object):
	def __str__(self):
		if self.value:
			return 'true'
		else:
			return 'false'

class ps_string(ps_object):
	def __str__(self):
		return "(%s)" % repr(self.value)[1:-1]

class ps_integer(ps_object):
	def __str__(self):
		return repr(self.value)

class ps_real(ps_object):
	def __str__(self):
		return repr(self.value)


class PSOperators(object):

	def ps_def(self):
		obj = self.pop()
		name = self.pop()
		self.dictstack[-1][name.value] = obj

	def ps_bind(self):
		proc = self.pop('proceduretype')
		self.proc_bind(proc)
		self.push(proc)

	def proc_bind(self, proc):
		for i in range(len(proc.value)):
			item = proc.value[i]
			if item.type == 'proceduretype':
				self.proc_bind(item)
			else:
				if not item.literal:
					try:
						obj = self.resolve_name(item.value)
					except:
						pass
					else:
						if obj.type == 'operatortype':
							proc.value[i] = obj

	def ps_exch(self):
		if len(self.stack) < 2:
			raise RuntimeError('stack underflow')
		obj1 = self.pop()
		obj2 = self.pop()
		self.push(obj1)
		self.push(obj2)

	def ps_dup(self):
		if not self.stack:
			raise RuntimeError('stack underflow')
		self.push(self.stack[-1])

	def ps_exec(self):
		obj = self.pop()
		if obj.type == 'proceduretype':
			self.call_procedure(obj)
		else:
			self.handle_object(obj)

	def ps_count(self):
		self.push(ps_integer(len(self.stack)))

	def ps_eq(self):
		any1 = self.pop()
		any2 = self.pop()
		self.push(ps_boolean(any1.value == any2.value))

	def ps_ne(self):
		any1 = self.pop()
		any2 = self.pop()
		self.push(ps_boolean(any1.value != any2.value))

	def ps_cvx(self):
		obj = self.pop()
		obj.literal = 0
		self.push(obj)

	def ps_matrix(self):
		matrix = [ps_real(1.0), ps_integer(0), ps_integer(0), ps_real(1.0), ps_integer(0), ps_integer(0)]
		self.push(ps_array(matrix))

	def ps_string(self):
		num = self.pop('integertype').value
		self.push(ps_string('\0' * num))

	def ps_type(self):
		obj = self.pop()
		self.push(ps_string(obj.type))

	def ps_store(self):
		value = self.pop()
		key = self.pop()
		name = key.value
		for i in range(len(self.dictstack)-1, -1, -1):
			if name in self.dictstack[i]:
				self.dictstack[i][name] = value
				break
		self.dictstack[-1][name] = value

	def ps_where(self):
		name = self.pop()
		# XXX
		self.push(ps_boolean(0))

	def ps_systemdict(self):
		self.push(ps_dict(self.dictstack[0]))

	def ps_userdict(self):
		self.push(ps_dict(self.dictstack[1]))

	def ps_currentdict(self):
		self.push(ps_dict(self.dictstack[-1]))

	def ps_currentfile(self):
		self.push(ps_file(self.tokenizer))

	def ps_eexec(self):
		f = self.pop('filetype').value
		f.starteexec()

	def ps_closefile(self):
		f = self.pop('filetype').value
		f.skipwhite()
		f.stopeexec()

	def ps_cleartomark(self):
		obj = self.pop()
		while obj != self.mark:
			obj = self.pop()

	def ps_readstring(self,
			ps_boolean=ps_boolean,
			len=len):
		s = self.pop('stringtype')
		oldstr = s.value
		f = self.pop('filetype')
		#pad = file.value.read(1)
		# for StringIO, this is faster
		f.value.pos = f.value.pos + 1
		newstr = f.value.read(len(oldstr))
		s.value = newstr
		self.push(s)
		self.push(ps_boolean(len(oldstr) == len(newstr)))

	def ps_known(self):
		key = self.pop()
		d = self.pop('dicttype', 'fonttype')
		self.push(ps_boolean(key.value in d.value))

	def ps_if(self):
		proc = self.pop('proceduretype')
		if self.pop('booleantype').value:
			self.call_procedure(proc)

	def ps_ifelse(self):
		proc2 = self.pop('proceduretype')
		proc1 = self.pop('proceduretype')
		if self.pop('booleantype').value:
			self.call_procedure(proc1)
		else:
			self.call_procedure(proc2)

	def ps_readonly(self):
		obj = self.pop()
		if obj.access < 1:
			obj.access = 1
		self.push(obj)

	def ps_executeonly(self):
		obj = self.pop()
		if obj.access < 2:
			obj.access = 2
		self.push(obj)

	def ps_noaccess(self):
		obj = self.pop()
		if obj.access < 3:
			obj.access = 3
		self.push(obj)

	def ps_not(self):
		obj = self.pop('booleantype', 'integertype')
		if obj.type == 'booleantype':
			self.push(ps_boolean(not obj.value))
		else:
			self.push(ps_integer(~obj.value))

	def ps_print(self):
		str = self.pop('stringtype')
		print('PS output --->', str.value)

	def ps_anchorsearch(self):
		seek = self.pop('stringtype')
		s = self.pop('stringtype')
		seeklen = len(seek.value)
		if s.value[:seeklen] == seek.value:
			self.push(ps_string(s.value[seeklen:]))
			self.push(seek)
			self.push(ps_boolean(1))
		else:
			self.push(s)
			self.push(ps_boolean(0))

	def ps_array(self):
		num = self.pop('integertype')
		array = ps_array([None] * num.value)
		self.push(array)

	def ps_astore(self):
		array = self.pop('arraytype')
		for i in range(len(array.value)-1, -1, -1):
			array.value[i] = self.pop()
		self.push(array)

	def ps_load(self):
		name = self.pop()
		self.push(self.resolve_name(name.value))

	def ps_put(self):
		obj1 = self.pop()
		obj2 = self.pop()
		obj3 = self.pop('arraytype', 'dicttype', 'stringtype', 'proceduretype')
		tp = obj3.type
		if tp == 'arraytype' or tp == 'proceduretype':
			obj3.value[obj2.value] = obj1
		elif tp == 'dicttype':
			obj3.value[obj2.value] = obj1
		elif tp == 'stringtype':
			index = obj2.value
			obj3.value = obj3.value[:index] + chr(obj1.value) + obj3.value[index+1:]

	def ps_get(self):
		obj1 = self.pop()
		if obj1.value == "Encoding":
			pass
		obj2 = self.pop('arraytype', 'dicttype', 'stringtype', 'proceduretype', 'fonttype')
		tp = obj2.type
		if tp in ('arraytype', 'proceduretype'):
			self.push(obj2.value[obj1.value])
		elif tp in ('dicttype', 'fonttype'):
			self.push(obj2.value[obj1.value])
		elif tp == 'stringtype':
			self.push(ps_integer(ord(obj2.value[obj1.value])))
		else:
			assert False, "shouldn't get here"

	def ps_getinterval(self):
		obj1 = self.pop('integertype')
		obj2 = self.pop('integertype')
		obj3 = self.pop('arraytype', 'stringtype')
		tp = obj3.type
		if tp == 'arraytype':
			self.push(ps_array(obj3.value[obj2.value:obj2.value + obj1.value]))
		elif tp == 'stringtype':
			self.push(ps_string(obj3.value[obj2.value:obj2.value + obj1.value]))

	def ps_putinterval(self):
		obj1 = self.pop('arraytype', 'stringtype')
		obj2 = self.pop('integertype')
		obj3 = self.pop('arraytype', 'stringtype')
		tp = obj3.type
		if tp == 'arraytype':
			obj3.value[obj2.value:obj2.value + len(obj1.value)] = obj1.value
		elif tp == 'stringtype':
			newstr = obj3.value[:obj2.value]
			newstr = newstr + obj1.value
			newstr = newstr + obj3.value[obj2.value + len(obj1.value):]
			obj3.value = newstr

	def ps_cvn(self):
		self.push(ps_name(self.pop('stringtype').value))

	def ps_index(self):
		n = self.pop('integertype').value
		if n < 0:
			raise RuntimeError('index may not be negative')
		self.push(self.stack[-1-n])

	def ps_for(self):
		proc = self.pop('proceduretype')
		limit = self.pop('integertype', 'realtype').value
		increment = self.pop('integertype', 'realtype').value
		i = self.pop('integertype', 'realtype').value
		while 1:
			if increment > 0:
				if i > limit:
					break
			else:
				if i < limit:
					break
			if type(i) == type(0.0):
				self.push(ps_real(i))
			else:
				self.push(ps_integer(i))
			self.call_procedure(proc)
			i = i + increment

	def ps_forall(self):
		proc = self.pop('proceduretype')
		obj = self.pop('arraytype', 'stringtype', 'dicttype')
		tp = obj.type
		if tp == 'arraytype':
			for item in obj.value:
				self.push(item)
				self.call_procedure(proc)
		elif tp == 'stringtype':
			for item in obj.value:
				self.push(ps_integer(ord(item)))
				self.call_procedure(proc)
		elif tp == 'dicttype':
			for key, value in obj.value.items():
				self.push(ps_name(key))
				self.push(value)
				self.call_procedure(proc)

	def ps_definefont(self):
		font = self.pop('dicttype')
		name = self.pop()
		font = ps_font(font.value)
		self.dictstack[0]['FontDirectory'].value[name.value] = font
		self.push(font)

	def ps_findfont(self):
		name = self.pop()
		font = self.dictstack[0]['FontDirectory'].value[name.value]
		self.push(font)

	def ps_pop(self):
		self.pop()

	def ps_dict(self):
		self.pop('integertype')
		self.push(ps_dict({}))

	def ps_begin(self):
		self.dictstack.append(self.pop('dicttype').value)

	def ps_end(self):
		if len(self.dictstack) > 2:
			del self.dictstack[-1]
		else:
			raise RuntimeError('dictstack underflow')

notdef = '.notdef'
from fontTools.encodings.StandardEncoding import StandardEncoding
ps_StandardEncoding = list(map(ps_name, StandardEncoding))
