from tkinter import Frame, Button
import json
import client

class Step(Frame):
	
	def __init__(self, parent, data, stepname): # parent is tkinter container, data is a dictionary where data will be stored, stepname is unique string and is the key for data in the dictionary
		super().__init__(parent)
		self.parent = parent
		self.data = data
		self.stepname = stepname

		# if stepname not in self.data: # initialize key/value in dictionary, creating nested dictionary
		# 	self.data[stepname] = {}
		# else:
		# 	print(stepname + " appears to be a duplicate of a previous step!")

		self.completed = True
		self.previous_enabled = True

	# Wizard Steps should call this once it is ok to advance to the next step
	# Will result in the "Next" or "Finish" buttons becoming enabled/interactive/not grayed out
	def _step_completed(self):
		self.completed = True
		self.parent.event_generate("<<step_complete>>", when="tail") # send event up to parent container (which should be the wizard)

	# Wizard Steps should call this if the user does something to make the wizard block clicking next
	# For instance, if there was a valid email address and now there isn't
	def _step_not_completed(self):
		self.completed = False
		self.parent.event_generate("<<step_not_complete>>", when="tail") # send event up to parent container (which should be the wizard)

	
	def onscreen_enter(self): # The Wizard calls this for the Step when it comes into view
		pass

	def onscreen_exit(self): # The Wizard calls this for the Step when it is removed from view
		pass

	def allow_previous(self):
		return self.previous_enabled

	def allow_next(self):
		return self.completed

class Wizard(Frame):
	
	def __init__(self, parent, data): # parent is tkinter container, data is a dictionary where data will be stored for each Wizard step
		super().__init__(parent)

		self.parent = parent

		self.current_step = None
		self.current_step_index = 0

		self.steps = []
		self.data = data
		self.button_frame = Frame(self, bd=1, relief="raised")
		self.content_frame = Frame(self)
		self.back_button = Button(self.button_frame, text="<< Back", command=self.back)
		self.next_button = Button(self.button_frame, text="Next >>", command=self.next)
		self.finish_button = Button(self.button_frame, text="Finish", command=self.finish)
		self.content_frame.pack(side="top", fill="both", expand=True) # self.content_frame.pack_propagate(0)  # Don't allow the widgets inside to determine the frame's width / height
		self.button_frame.pack(side="bottom", fill="x") # self.button_frame.pack_propagate(0)
		self.bind("<<step_complete>>", self.step_complete) # register for events that steps might pass up to the wizard
		self.bind("<<step_not_complete>>", self.step_not_complete)

		# Example custom event call for above bind()
		# self.event_generate("<<step_complete>>", when="tail")

	def step_complete(self, event):
		# print("Wizard:step_complete()")
		self.next_button.config(state="normal")
		self.finish_button.config(state="normal")

	def step_not_complete(self, event):
		# print("Wizard:step_complete()")
		self.next_button.config(state="disabled")
		self.finish_button.config(state="disabled")

	def set_steps(self, steps):
		self.steps = steps

	def start(self):
		self.show_step(self.current_step_index)

	def back(self):
		self.current_step_index -= 1
		self.show_step(self.current_step_index)

	def next(self):
		self.current_step_index += 1
		self.show_step(self.current_step_index)
	
	def finish(self):
		
		self.current_step_index = 0
		print("data is: ")
		pretty_data = json.dumps(self.data, indent=4)
		print(pretty_data)
		client.make_call(self.data)
		
		self.parent.quit()

	def show_step(self, step):

		if step < len(self.steps):
			if self.current_step is not None: # remove current step and tell the step it is going off screen
				self.current_step.onscreen_exit()
				self.current_step.pack_forget()

			self.current_step = self.steps[step]
			self.current_step.pack(fill="both", expand=True)
			self.current_step.onscreen_enter() # Tell the step it's going up on the screen

		if len(self.steps) != 0:
			if len(self.steps) == 1:
				self.back_button.pack_forget()
				self.next_button.pack_forget()
				self.finish_button.pack(side="right")
			elif step == 0: # first
				self.back_button.pack_forget()
				self.next_button.pack(side="right")
				self.finish_button.pack_forget()
			elif step == len(self.steps) - 1: # last
				self.back_button.pack(side="left")
				self.next_button.pack_forget()
				self.finish_button.pack(side="right")

			else: # all other steps
				self.back_button.pack(side="left")
				self.next_button.pack(side="right")
				self.finish_button.pack_forget()
		else:
			self.back_button.pack_forget()
			self.next_button.pack_forget()
			self.finish_button.pack(side="right")

		if self.current_step is not None:
			if self.current_step.allow_next():
				self.next_button.config(state="normal")
				self.finish_button.config(state="normal")
			else:
				self.next_button.config(state="disabled")
				self.finish_button.config(state="disabled")

			if not self.current_step.allow_previous():
				self.back_button.pack_forget()