#initial setup win32com
import win32com
#import client to use dispatching methods
from win32com import client

from win32com.client import makepy
makepy.main()
S8 = win32com.client.Dispatch("Simul8.S8Simulation")

import win32com.client
import pythoncom

# Initialize a looping variable (used later), this helps us control the commands and when they are excecuted
# This can be called whatever you want
listenForMessages = True

# This class will handle the events, we define these before we initialize the Simulation
class EventHandler:
    def OnS8SimulationOpened(self):
        print("The Simulation has been opened.")
        # Run Simulation for a set length - in this case 1000 minutes
        S8.RunSim(3000)
    # Define your events and what happens when the event is triggered
    def OnS8SimulationEndRun(self):
        # We make our looping variable global so that it can be used inside and outside of this event class
        global listenForMessages 
        
        print("The simulation run has ended.")
        
        # Show results in the console
        print("Simulation Results:")
        n = 1
        while n <= S8.ResultsCount:
            print(S8.Results(n))
            n += 1
            
        # Finally it is important to trigger the end of our python loop. 
        # This could be in any kind of event but I find at the end of the run most useful.
        listenForMessages = False 

# Initialize COM Libraries
pythoncom.CoInitialize()

# Open Simul8
# Note: Here you are giving control of Simul8 to COM. You may not be able to control this instance manually until you release it from COM or close your kernel.
S8 = win32com.client.Dispatch("Simul8.S8Simulation")

# Set up event handling with our event class from above
events = win32com.client.WithEvents(S8, EventHandler)

# Opens a Simulation file
S8.Open(r"C:\Users\JohnSmith\Desktop\COM PDF Example.S8")

# Start a loop to listen for events
# This stops python from going any further before the simulation has run and my end condition is met.
while listenForMessages:
    # During this loop, I want to pass any messages to my console. This is needed in most IDEs
    pythoncom.PumpWaitingMessages()

# Once out of the loop, close the simulation.
S8.Close() 

# Finally you should Uninitialize COM Libraries
pythoncom.CoUninitialize()

#Below is the code for the Result PDF that will use the result from he run set in the CSV file.

from reportlab.lib.colors import HexColor
from reportlab.lib.pagesizes import letter
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.units import inch
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, Image, Frame, PageTemplate
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt


# Define font styles
pdfmetrics.registerFont(TTFont('Arial', 'arial.ttf'))

title_style = ParagraphStyle(
    name='title_style',
    fontName='Arial',
    fontSize=64,
    leading=86,
    textColor=HexColor('#23529e'),
)

table_header_style = ParagraphStyle(
    name='table_header_style',
    fontName='Arial',
    fontSize=16,
    leading=14,
    textColor=HexColor('#23529e'),
)


paragraph_style = ParagraphStyle(
    name='paragraph_style',
    fontName='Arial',
    fontSize=14,
    leading=18,
    textColor=HexColor('#1e223e'),
)


# Read CSV file
df = pd.read_csv(r"C:\Users\JohnSmith\Desktop\PythonCOM.csv")

# Select relevant columns
dfm = df.iloc[:, 2:8]
dfm = dfm.melt(var_name='Machines', value_name='Working Time (%)')
df_table = df.iloc[:, 7:10]
df_table = df_table.melt(var_name='Resource', value_name='Utilisation')
completed_work_items = df['Completed '][0]
defective_work_items = df['Defect'][0]


# Add column names to DataFrame
df_table.columns = ['Resource Type', 'Utilisation (%)']

# Convert DataFrame to list of lists for use in Table object
# If an average of several runs is wanted use the commented out section below
table_data = [df_table.columns.tolist()] + df_table.values.tolist()
#df_means = df_table.groupby(['Resource Type'], as_index=False).mean('Utilisation')
#table_data = [df_means.columns.tolist()] + df_means.values.tolist()

# Create bubble chart
colors = ['#2dab66', '#23529e', '#12a19a', '#5580c0']
sns.set_palette(sns.color_palette(colors))
chart = sns.barplot(x='Machines', y='Working Time (%)', data=dfm, hue="Machines", palette=('Blues_d'))


# Create PDF document
doc = SimpleDocTemplate(r"C:\Users\JohnSmith\Desktop\Simul8_Results.pdf", pagesize=letter)

# Add the PageTemplate to the doc object


# Add title and paragraph to PDF elements
elements = []

title = Paragraph('Simul8 Report', title_style)
elements.append(title)

spacer_title = Spacer(1, 0.15*inch)
elements.append(spacer_title)

# Add paragraph with simulation results
simulation_results = f'Overall {completed_work_items} Work Items were completed within the simulation time with {defective_work_items} Work Items being defective upon completion. Below is a table of the Resource Utilisation (%) of the run as well as a chart of the individual machines Working Time (%).'
paragraph = Paragraph(simulation_results, paragraph_style)
elements.append(paragraph)

spacer_Paragraph = Spacer(1, 0.35*inch)
elements.append(spacer_Paragraph)

# Add table to PDF elements
table = Table(table_data, colWidths=[2*inch, 2*inch])
table.setStyle(TableStyle([
    ('BACKGROUND', (0, 0), (-1, 0), HexColor('#cbe4f7')),
    ('TEXTCOLOR', (0, 0), (-1, 0), HexColor('#1e223e')),
    ('FONTNAME', (0, 0), (-1, 0), 'Arial'),
    ('FONTSIZE', (0, 0), (-1, 0), 18),
    ('LEADING', (0, 0), (-1, 0), 24),
    ('ALIGN', (0, 0), (-1, 0), 'CENTER'),
    ('GRID', (0, 0), (-1, -1), 0.5, HexColor('#1e223e')),
    ('FONTNAME', (0, 1), (-1, -1), 'Arial'),
    ('FONTSIZE', (0, 1), (-1, -1), 14),
    ('LEADING', (0, 1), (-1, -1), 14),
    ('ALIGN', (0, 1), (-1, -1), 'CENTER'),
]))
elements.append(table)

spacer_table = Spacer(1, 0.35*inch)
elements.append(spacer_table)

# Add title for chart
chart_title = Paragraph('Machine Working Time within the Simulation Run (%)', paragraph_style)
elements.append(chart_title)

spacer_chart = Spacer(1, 0.05*inch)
elements.append(spacer_chart)

# Add chart
fig = chart.get_figure()
fig.savefig('chart.png')
chart_image = Image('chart.png')
chart_image.drawHeight = 4*inch
chart_image.drawWidth = 6*inch
elements.append(chart_image)


doc.build(elements)

#Open the Pdf
import subprocess
subprocess.Popen([r"C:\Users\JohnSmith\Desktop\Simul8_Results.pdf"],shell=True)
