text: # Copyright YukonTR 2015
  
  from random import random
  
  import simpy
  
  from model.producer import Producer
  from model.location import Location
  from model.vehicle import Vehicle
  from model.arrival_stochastics import ArrivalStochastics
  from model.deliverymanager import DeliveryManager
  from core_utilities.exportplot import ExportPlot
  
  class SimulationAdmin(object):
      def __init__(self, worldsize=100.0):
          self.worldsize = worldsize
          self.producer_list = None
          self.pindexerGet = None
          self.workorder_list = list()
          self.vehicle_list = None
          self.arrivalstats_list = None
          # create simulation environment
          self.env = simpy.Environment()
          self.deliverymgr = DeliveryManager(env=self.env)
  
      # create list of producers, each producer is attached with workorder-related parameters
      # also generate list of work orders for this producer
      def create_producer_list(self, producerinfo_list=None, producer_num=1):
          if producerinfo_list:
              self.producer_list = [Producer(pid=x["pid"], location=Location(x=x["x"], y=x["y"]),
                                             production_time=x["production_time"],
                                             env=self.env, deliverymgr=self.deliverymgr)
                                    for x in producerinfo_list]
          else:
              for i in range(producer_num):
                  producer = Producer(i+1, worldsize=self.worldsize, env=self.env)
                  self.producer_list.append(producer)
          self.pindexerGet = lambda x: dict((p.pid,i) for i,p in enumerate(
              self.producer_list)).get(x)
  
      def create_customerorder_list(self, orderinfo_list):
          # random generation of customer(s) location
          for orderinfo in orderinfo_list:
              customer_loc_list = [Location(self.worldsize*random(), self.worldsize*random())
                                   for i in range(orderinfo["workorder_num"])]
              orderinfo.update({"customer_loc_list":customer_loc_list})
          self.workorder_list = orderinfo_list
          # create processes that specify arrival statistics and manage processes initiated upon
          # workorder arrival
          self.arrivalstats_list = [
              {"pid":x["pid"],
               "arrival_obj": ArrivalStochastics(
                   env=self.env, lambd_rate=x["lambd_rate"], dist_type=x["dist_type"],
                   customer_loc_list=x["customer_loc_list"], pid=x["pid"],
                   producer_action=self.producer_list[self.pindexerGet(x["pid"])].producer_action)}
                   #interrupt_process=self.producer_list[self.pindexerGet(x["pid"])].action_process)}
              for x in self.workorder_list]
  
      def create_vehicle_list(self, vehicleinfo_list):
          self.vehicle_list = [Vehicle(env=self.env, vid=x["vid"], initial_location=Location(x["x"],x["y"]),
                                       capacity=x["capacity"], velocity=x["velocity"]) for x in vehicleinfo_list]
  
      def prepare_simulation(self, producerinfo_list, vehicleinfo_list, orderinfo_list):
          # create list of producer of goods
          self.create_producer_list(producerinfo_list=producerinfo_list)
          # create list of orders generated by customer/consumers
          self.create_customerorder_list(orderinfo_list)
          # create list of vehicle resources
          self.create_vehicle_list(vehicleinfo_list)
          # initiate delivery manager and assign available vehicle resources
          self.deliverymgr.vehicle_list = self.vehicle_list
  
      # top level simulation run control; instantiate individual arrival poisson processes, along with
      # processes that will be interrupted when workorder arrival is triggered
      def simulation_run(self, timeinterval):
          # run the simulation
          self.env.run(until=timeinterval)
  
      def export_results(self):
          ep = ExportPlot("arrivalprocesses")
          arrivalhistory_list = [x["arrival_obj"].arrival_history for x in self.arrivalstats_list]
          ep.group_plot(arrivalhistory_list)
  
      def __str__(self):
          return_str = "SimulationAdmin Info:\n"
          for p in self.producer_list:
              return_str += str(p) + "\n"
          return_str += "workorder info:\n"
          for workorder_param in self.workorder_list:
              return_str += str(workorder_param)
          return return_str
  