def generate_image():
  if middle_section == 'inkycal_agenda' and internet_available() == True:
    try:
      clear_image('middle_section')
      if not bottom_section:
        clear_image('bottom_section')

      print('Agenda module: Generating image...', end = '')
      now = arrow.now(get_tz())
      today_start = arrow.get(now.year, now.month, now.day)

      """Create a list of dictionaries containing dates of the next days"""
      agenda_events = [{'date':today_start.replace(days=+_),
        'date_str': now.replace(days=+_).format('ddd D MMM',locale=language),
        'type':'date'} for _ in range(max_lines)]

      """Copy the list from the icalendar module with some conditions"""
      upcoming_events = fetch_events()
      filtered_events = [events for events in upcoming_events if
                         events.end > now]

      """Set print_events_to True to print all events in this month"""
      if print_events == True and filtered_events:
        auto_line_width = max(len(_.name) for _ in filtered_events)
        for events in filtered_events:
          print('{0} {1} | {2} | {3} | All day ='.format(events.name,
            ' '* (auto_line_width - len(events.name)), events.begin.format(style),
            events.end.format(style)), events.all_day)

      """Convert the event-timings from utc to the specified locale's time
      and create a ready-to-display list for the agenda view"""
      for events in filtered_events:
        if not events.all_day:
          agenda_events.append({'date': events.begin, 'time': events.begin.format(
            'HH:mm' if hours == '24' else 'hh:mm a'), 'name':str(events.name),
            'type':'timed_event'})
        else:
          if events.duration.days == 1:
            agenda_events.append({'date': events.begin,'time': all_day_str,
                                  'name': events.name,'type':'full_day_event'})
          else:
            for day in range(events.duration.days):
              agenda_events.append({'date': events.begin.replace(days=+day),
                'time': all_day_str,'name':events.name, 'type':'full_day_event'})

      """Sort events and dates in chronological order"""
      agenda_events = sorted(agenda_events, key = lambda event: event['date'])
      
      """Removes duplicate events"""
      prev_event = {}
      for event in list(agenda_events):
          if event == prev_event:
              agenda_events.remove(event)
          else:
              prev_event = event
       
      """Crop the agenda_events in case it's too long"""
      del agenda_events[max_lines:]

      """Display all events, dates and times on the display"""
      if show_events == True:
        previous_date = None
        for events in range(len(agenda_events)):
          if agenda_events[events]['type'] == 'date':
            if previous_date == None or previous_date != agenda_events[events][
              'date']:
              write_text(date_col_width, line_height,
                agenda_events[events]['date_str'], line_pos[events], font = font)

            previous_date = agenda_events[events]['date']
            
            if three_colour_support == True:
              draw_col.line((date_col_start, line_pos[events][1],
              line_width,line_pos[events][1]), fill = 'black')
            else:
              draw.line((date_col_start, line_pos[events][1],
              line_width,line_pos[events][1]), fill = 'black')
              

          elif agenda_events[events]['type'] == 'timed_event':
            write_text(time_col_width, line_height, agenda_events[events]['time'],
              (time_col_start, line_pos[events][1]), font = font)

            write_text(event_col_width, line_height, ('• '+agenda_events[events][
              'name']), (event_col_start, line_pos[events][1]),
               alignment = 'left', font = font)

          else:
            write_text(time_col_width, line_height, agenda_events[events]['time'],
              (time_col_start, line_pos[events][1]), font = font)

            write_text(event_col_width, line_height, ('• '+agenda_events[events]['name']),
              (event_col_start, line_pos[events][1]), alignment = 'left', font = font)

      """Crop the image to show only the middle section"""
      agenda_image = image.crop((0,middle_section_offset,display_width, display_height))
      agenda_image.save(image_path+'inkycal_agenda.png')

      if three_colour_support == True:
        agenda_image_col = image_col.crop((0,middle_section_offset,display_width, display_height))
        agenda_image_col.save(image_path+'inkycal_agenda_col.png')

      print('Done')

    except Exception as e:
      """If something went wrong, print a Error message on the Terminal"""
      print('Failed!')
      print('Error in Agenda module!')
      print('Reason: ',e)
      
      clear_image('middle_section')
      write_text(middle_section_width, middle_section_height, str(e),
                 (0, middle_section_offset), font = font)
      calendar_image = crop_image(image, 'middle_section')
      calendar_image.save(image_path+'inkycal_agenda.png')
      pass
def generate_image():
  if middle_section == "inkycal_calendar" and internet_available() == True:
    try:
      clear_image('middle_section')
      print('Calendar module: Generating image...', end = '')
      now = arrow.now(tz = get_tz())

      """Set up the Calendar template based on personal preferences"""
      if week_starts_on == "Monday":
        calendar.setfirstweekday(calendar.MONDAY)
        weekstart = now.replace(days = - now.weekday())
      else:
        calendar.setfirstweekday(calendar.SUNDAY)
        weekstart = now.replace(days = - now.isoweekday())

      """Write the name of the current month at the correct position"""
      write_text(main_area_width, month_name_height,
        str(now.format('MMMM',locale=language)), (border_left,
        middle_section_offset), autofit = True)

      """Set up weeknames in local language and add to main section"""
      weekday_names = [weekstart.replace(days=+_).format('ddd',locale=language)
        for _ in range(7)]

      for _ in range(len(weekday_pos)):
        write_text(icon_width, weekdays_height, weekday_names[_],
                   weekday_pos[_], autofit = True)

      """Create a calendar template and flatten (remove nestings)"""
      flatten = lambda z: [x for y in z for x in y]
      calendar_flat = flatten(calendar.monthcalendar(now.year, now.month))

      """Add the numbers on the correct positions"""
      for i in range(len(calendar_flat)):
        if calendar_flat[i] != 0:
          write_text(icon_width, icon_height, str(calendar_flat[i]), grid[i])

      """Draw a red/black circle with the current day of month in white"""
      icon = Image.new('RGBA', (icon_width, icon_height))
      current_day_pos = grid[calendar_flat.index(now.day)]
      x_circle,y_circle = int(icon_width/2), int(icon_height/2)
      radius = int(icon_width * 0.25)
      text_width, text_height = default.getsize(str(now.day))
      x_text = int((icon_width / 2) - (text_width / 2))
      y_text = int((icon_height / 2) - (text_height / 1.7))
      ImageDraw.Draw(icon).ellipse((x_circle-radius, y_circle-radius,
        x_circle+radius, y_circle+radius), fill= 'red' if
        three_colour_support == True else 'black', outline=None)
      ImageDraw.Draw(icon).text((x_text, y_text), str(now.day), fill='white',
        font=bold)
      image.paste(icon, current_day_pos, icon)

      """Create some reference points for the current month"""
      days_current_month = calendar.monthrange(now.year, now.month)[1]
      month_start = now.floor('month')
      month_end = now.ceil('month')

      if show_events == True:
        """Filter events which begin before the end of this month"""
        upcoming_events = fetch_events()

        calendar_events = [events for events in upcoming_events if
          month_start <= events.end <= month_end ]

        """Find days with events in the current month"""
        days_with_events = []
        for events in calendar_events:
          if events.duration.days <= 1:
            days_with_events.append(int(events.begin.format('D')))
          else:
            for day in range(events.duration.days):
              days_with_events.append(
                int(events.begin.replace(days=+i).format('D')))
        days_with_events = set(days_with_events)

        if event_icon == 'dot':
          for days in days_with_events:
            write_text(icon_width, int(icon_height * 0.2), '•',
              (grid[calendar_flat.index(days)][0],
               int(grid[calendar_flat.index(days)][1] + icon_height*0.8)))

        if event_icon == 'square':
          square_size = int(icon_width * 0.6)
          center_x = int((icon_width - square_size) / 2)
          center_y = int((icon_height - square_size) / 2)
          for days in days_with_events:
            draw_square((int(grid[calendar_flat.index(days)][0]+center_x),
               int(grid[calendar_flat.index(days)][1] + center_y )),
               8, square_size , square_size)


        """Add a small section showing events of today and tomorrow"""
        event_list = ['{0} {1} {2} : {3}'.format(today_in_your_language,
          at_in_your_language, event.begin.format('HH:mm' if hours == 24 else
          'hh:mm'), event.name) for event in calendar_events if event.begin.day
          == now.day and now < event.end]

        event_list += ['{0} {1} {2} : {3}'.format(tomorrow_in_your_language,
          at_in_your_language, event.begin.format('HH:mm' if hours == 24 else
          'hh:mm'), event.name) for event in calendar_events if event.begin.day
          == now.replace(days=1).day]

        after_two_days = now.replace(days=2).floor('day')

        event_list += ['{0} {1} {2} : {3}'.format(event.begin.format('D MMM'),
          at_in_your_language, event.begin.format('HH:mm' if hours == 24 else
          'hh:mm'), event.name) for event in upcoming_events if event.end >
           after_two_days]

        del event_list[max_event_lines:]

      if event_list:
        for lines in event_list:
          write_text(main_area_width, int(events_height/max_event_lines), lines,
            event_lines[event_list.index(lines)], alignment='left',
            fill_height = 0.7)
      else:
        write_text(main_area_width, int(events_height/max_event_lines),
         'No upcoming events.', event_lines[0], alignment='left',
         fill_height = 0.7)

      """Set print_events_to True to print all events in this month"""
      style = 'DD MMM YY HH:mm'
      if print_events == True and calendar_events:
        line_width = max(len(_.name) for _ in calendar_events)
        for events in calendar_events:
          print('{0} {1} | {2} | {3} | All day ='.format(events.name,
            ' ' * (line_width - len(events.name)), events.begin.format(style),
            events.end.format(style)), events.all_day)

      calendar_image = crop_image(image, 'middle_section')
      calendar_image.save(image_path+'inkycal_calendar.png')

      print('Done')

    except Exception as e:
      """If something went wrong, print a Error message on the Terminal"""
      print('Failed!')
      print('Error in Calendar module!')
      print('Reason: ',e)
      pass