docs: def draw_state(self, name, pos, size, outcomes=None, input_ports_m=None, output_ports_m=None, selected=False,
                     active=False, depth=0):
          """Draw a state with the given properties
  
          This method is called by the controller to draw the specified (container) state.
  
          :param name: Name of the state
          :param pos: position (x, y) of the state
          :param size: size (width, height) of the state
          :param outcomes: outcomes of the state (list with outcome objects)
          :param input_ports_m: input ports of the state
          :param output_ports_m: output ports of the state
          :param selected: whether to display the state as selected
          :param active: in which color to display the state
          :param depth: The z layer
          :return: The OpenGL id and the positions of teh outcomes (as dictionary with outcome id as key)
          """
          if not outcomes:
              outcomes = []
          if not input_ports_m:
              input_ports_m = []
          if not output_ports_m:
              output_ports_m = []
          # "Generate" unique ID for each object
          opengl_id = self.name_counter
          self.name_counter += 1
          glPushName(opengl_id)
          self._set_closest_stroke_width(1.5)
  
          width = size[0]
          height = size[1]
  
          # First draw the face of the rectangular, then the outline
          fill_color = self.state_color
          border_color = self.border_color
  
          from rafcon.core.states.state import StateExecutionStatus
          border_width = min(size) / 10.
          if active is StateExecutionStatus.ACTIVE:
              fill_color = self.state_active_color
          elif active is StateExecutionStatus.EXECUTE_CHILDREN:
              fill_color = self.state_child_active_color
          elif active is StateExecutionStatus.WAIT_FOR_NEXT_STATE:
              fill_color = self.state_waiting_for_next_state_color
  
          if selected:
              border_width *= 2
              border_color = self.border_selected_color
  
          self._draw_rect(pos[0], pos[0] + width, pos[1] - height, pos[1], depth, border_width,
                          fill_color, border_color)
  
          # Put the name of the state in the upper left corner of the state
          margin = min(size) / 12.
          font_size = min(size) / 8.
          name = self._shorten_string(name, font_size, width - 2 * margin)
          self._write_string(name, pos[0] + margin, pos[1] - margin, font_size, self.state_name_color, True,
                             False, depth=depth + 0.01)
  
          resize_length = min(width, height) / 8.
          p1 = (pos[0] + width, pos[1] - height)
          p2 = (p1[0] - resize_length, p1[1])
          p3 = (p1[0], p1[1] + resize_length)
          self._draw_triangle(p1, p2, p3, depth + 0.01, border_width, fill_color, border_color)
  
          # Draw outcomes as circle on the right side of the state
          # Every state has at least the default outcomes "aborted" and "preempted"
          num_outcomes = max(0, len(outcomes))
          if num_outcomes < 2:
              # logger.warning("Expecting at least 2 outcomes, found {num:d}".format(num=num_outcomes))
              pass
          else:
              num_outcomes -= 2
          i = 0
          outcome_pos = {}
          outcome_radius = min(min(height, width) / 23., min(height, width) / (2. * num_outcomes + 3))
          for key in outcomes:
              # Color of outcome is defined by its type, "aborted", "preempted" or else
              outcome_name = outcomes[key].name
              color = self.outcome_plain_color
  
              # Distribute outcomes (as circles) on the right edge of the state
              outcome_x = pos[0] + width
              outcome_y = pos[1] - height / (num_outcomes + 1) * (i + 1)
  
              if outcome_name in ["aborted", "preempted"]:
                  step = min(size) / 10.
                  outcome_y = pos[1]
                  if outcome_name == "aborted":
                      outcome_x -= step
                      color = self.outcome_aborted_color
                  else:
                      outcome_x -= 3 * step
                      color = self.outcome_preempted_color
              else:
                  outcome_font_size = font_size * 0.5
                  max_outcome_name_width = width / 2.
                  outcome_name = self._shorten_string(outcome_name, outcome_font_size, max_outcome_name_width)
                  outcome_name_pos_x = outcome_x - margin
                  outcome_name_pos_y = outcome_y + outcome_font_size * 0.65
                  self._write_string(outcome_name, outcome_name_pos_x, outcome_name_pos_y, outcome_font_size,
                                     self.state_name_color, align_right=True, depth=depth+0.1)
                  i += 1
  
              color.set()
              outcome_pos[key] = (outcome_x, outcome_y)
  
              self._draw_circle(outcome_x, outcome_y, outcome_radius, depth + 0.1, fill_color=color)
  
          # Draw "income" as a half circle of the left center
          income_pos = (pos[0], pos[1] - height / 2)
          self._draw_circle(income_pos[0], income_pos[1], outcome_radius, depth + 0.1, fill_color=self.income_color,
                            from_angle=1.5 * pi, to_angle=0.5 * pi)
  
          # Draw input and output data ports
          port_radius = margin / 4.
          num_ports = len(input_ports_m) + len(output_ports_m)
          if num_ports > 0:
              max_name_width = 0
              margin = min(size) / 10.0
              max_allowed_name_width = 0.7 * width - margin
              str_height = height / 12.0
  
              # Determine the maximum width of all port labels
              for ports in [input_ports_m, output_ports_m]:
                  for port_m in ports:
                      str_width = self._string_width(port_m.data_port.name, str_height)
                      if str_width > max_name_width:
                          max_name_width = str_width
  
              #fill_color = self.port_color if not selected else self.state_selected_color
  
              port_width = min(max_name_width, max_allowed_name_width)
              port_pos_left_x = pos[0] + (width - port_width - margin) / 2
              port_pos_right_x = port_pos_left_x + port_width + margin
              port_pos_bottom_y = pos[1] - height - num_ports * (str_height + margin)
              self._draw_rect(port_pos_left_x, port_pos_right_x, port_pos_bottom_y, pos[1] - height, depth, border_width,
                              fill_color, border_color)
  
              def draw_port(port_m, num, is_input):
  
                  port_name = self._shorten_string(port_m.data_port.name, str_height, port_width)
  
                  string_pos_x = port_pos_left_x + margin / 2.
                  if not is_input:
                      string_pos_x += port_width
                  string_pos_y = pos[1] - height - margin / 2. - num * (str_height + margin)
                  self._write_string(port_name, string_pos_x, string_pos_y,
                                     str_height, self.port_name_color, False, not is_input, depth + 0.01)
  
                  circle_pos_x = port_pos_left_x if is_input else port_pos_right_x
                  circle_pos_y = string_pos_y - margin / 2.
                  self._draw_circle(circle_pos_x, circle_pos_y, port_radius, depth + 0.02, stroke_width=margin / 5.,
                                    border_color=self.port_name_color, fill_color=self.port_connector_fill_color)
                  return circle_pos_x, circle_pos_y
  
              output_num = 0
              for port_m in input_ports_m:
                  con_pos_x, con_pos_y = draw_port(port_m, output_num, True)
                  port_m.temp['gui']['editor']['outer_connector_radius'] = port_radius
                  port_m.temp['gui']['editor']['outer_connector_pos'] = (con_pos_x, con_pos_y)
                  output_num += 1
  
              for port_m in output_ports_m:
                  con_pos_x, con_pos_y = draw_port(port_m, output_num, False)
                  port_m.temp['gui']['editor']['outer_connector_radius'] = port_radius
                  port_m.temp['gui']['editor']['outer_connector_pos'] = (con_pos_x, con_pos_y)
                  output_num += 1
  
          glPopName()
          return opengl_id, income_pos, outcome_pos, outcome_radius, resize_length