/**
     * Provides the meta box for editinig the venue address.
     *
     * The box provides input fields for the addres and map location of the venue.
     *
     * @param object $post
     */
    public static function btb_venue_address_box($post)
    {
        $venue = btb_get_venue($post->ID);
        wp_localize_script('btb-edit-venue-script', 'BTBooking', array('lat' => $venue->latitude, 'lng' => $venue->longitude, 'queryErrorMsg' => __('When querying the data an error has occurred.', 'bt-booking'), 'nothingFoundMsg' => __('For the specified address no place could be found.', 'bt-booking')));
        wp_enqueue_script('btb-edit-venue-script');
        wp_nonce_field('btb_save_venue_address_box_data', 'btb_venue_address_box_nonce');
        // Creating first row, showing street name and house number
        $row1 = new BTCTableRow();
        $row1->add_content(BTCWPAdminInputText::create('btb_address_street', esc_html__('Street', 'bt-booking'), $venue->street));
        $row1->add_content(BTCWPAdminInputText::create('btb_address_number', esc_html__('Number', 'bt-booking'), $venue->house_number));
        // Creating second row, showing postal code and city
        $row2 = new BTCTableRow();
        $row2->add_content(BTCWPAdminInputText::create('btb_address_zip', esc_html__('Postal code', 'bt-booking'), $venue->postal_code));
        $row2->add_content(BTCWPAdminInputText::create('btb_address_city', esc_html__('City', 'bt-booking'), $venue->city));
        // Creating third row, showing state/region and country
        $row3 = new BTCTableRow();
        $row3->add_content(BTCWPAdminInputText::create('btb_address_region', esc_html__('State/Region', 'bt-booking'), $venue->region));
        $row3->add_content(BTCWPAdminInputSelect::create('btb_address_country', esc_html__('Country', 'bt-booking'), $venue->country, BTBookingCountries::get_countries()));
        // Creating fourth row, showing switch for using map coordinates
        $row4 = new BTCTableRow();
        $row4->add_content(BTCWPAdminInputCheckbox::create('btb_use_coordinates', esc_html__('Use map coordinates', 'bt-booking'), $venue->use_map_coords));
        $row4->add_content(new BTCTableData());
        $saButtonAttrs = array('id' => 'search_address', 'type' => 'button', 'htmlClasses' => 'button button-small');
        if (!$venue->use_map_coords) {
            $saButtonAttrs["style"] = "display:none";
        }
        $row4->add_content(new BTCTableData(new BTCFormButton($saButtonAttrs, esc_html__('Search address', 'bt-booking'))));
        $table = new BTCTable(array('htmlClasses' => 'form-table'), new BTCTableBody(array(), array($row1, $row2, $row3, $row4)));
        $table->render();
        $loc_table = new BTCTable(array('id' => 'locs_table', 'htmlClasses' => 'form-table', 'style' => 'display:none;'));
        $loc_head_row = new BTCTableRow();
        $thstyle = array('padding' => '15px 10px');
        $loc_head_row->add_content(new BTCTableData(esc_html__('Choose', 'bt-booking'), array('style' => $thstyle), true));
        $loc_head_row->add_content(new BTCTableData(esc_html__('Street & No.', 'bt-booking'), array('style' => $thstyle), true));
        $loc_head_row->add_content(new BTCTableData(esc_html__('City', 'bt-booking'), array('style' => $thstyle), true));
        $loc_head_row->add_content(new BTCTableData(esc_html__('ZIP', 'bt-booking'), array('style' => $thstyle), true));
        $loc_head_row->add_content(new BTCTableData(esc_html__('State', 'bt-booking'), array('style' => $thstyle), true));
        $loc_head = new BTCTableHead(array(), $loc_head_row);
        $loc_body = new BTCTableBody(array('id' => 'locs_body'));
        $loc_table->head = $loc_head;
        $loc_table->body = $loc_body;
        $loc_table->render();
        ?>
		<input type="hidden" id="btb_address_lat" name="btb_address_lat" value="<?php 
        echo $venue->latitude;
        ?>
">
		<input type="hidden" id="btb_address_lon" name="btb_address_lon" value="<?php 
        echo $venue->longitude;
        ?>
">

		<div id="mapMessages">
		</div>

		<div id="venueMap" style="height:300px;<?php 
        echo $venue->use_map_coords ? '' : ' display:none';
        ?>
">
		</div>

		<?php 
    }
 /**
  * Processes the btb_direct_booking shortcode.
  *
  * If the booking process is started, it takes the POST data and creates a new booking post item
  * for further processing.
  *
  * @param array $atts See class description for explanation.
  */
 public static function direct_booking_func($atts)
 {
     date_default_timezone_set(get_option('timezone_string', 'UTC'));
     $master_instance = get_option('btb_instance_type', 'master') == 'master';
     if (!empty($_POST)) {
         if (!wp_verify_nonce($_POST['btb_direct_booking_nonce'], 'btb_direct_booking_data')) {
             return;
         }
         if (!isset($_POST['btb_booking_event_id']) || !isset($_POST['btb_booking_amount']) || !isset($_POST['btb_booking_time'])) {
             return;
         }
         $event_id = intval($_POST['btb_booking_event_id']);
         $time_id = intval($_POST['btb_booking_time']);
         $amount = intval($_POST['btb_booking_amount']);
         if ($master_instance) {
             $free_slots = btb_get_time_free_slots($time_id);
         } else {
             $time = btb_get_time_from_api($time_id, OBJECT, 'display');
             $event = btb_get_event_from_api($event_id, OBJECT, 'display');
             $free_slots = $time->free_slots;
         }
         if ($free_slots >= $amount) {
             if ($master_instance) {
                 $timeprice = floatval(get_post_meta($time_id, 'btb_price', true));
                 $eventprice = floatval(get_post_meta($event_id, 'btb_price', true));
             } else {
                 $timeprice = floatval($time->price);
                 $eventprice = floatval($event->price);
             }
             $price = $timeprice ? $timeprice : $eventprice;
             if ($master_instance) {
                 $new_booking = btb_create_booking($event_id, $time_id, array('btb_slots' => $amount, 'btb_booking_time' => time(), 'btb_price' => $price));
             } else {
                 $new_booking = btb_create_booking_via_api($time_id, array('btb_slots' => $amount, 'btb_booking_time' => time(), 'btb_price' => $price));
             }
             if ($new_booking) {
                 $nonce = wp_create_nonce('btb_direct_booking_nonce');
                 echo printf('<script>window.location.href = "%s?booking=%u&btbnonce=%s";</script>', get_permalink(get_option('btb_checkout_page')), $new_booking, $nonce);
             }
         } else {
             if (abs($free_slots - $amount) < $amount && abs($free_slots - $amount) > 0) {
                 return '<p>' . esc_html__('There are not enough free slots for your selection.', 'bt-booking') . '</p>';
             } else {
                 return '<p>' . esc_html__('This is now booked out.', 'bt-booking') . '</p>';
             }
         }
     }
     $a = shortcode_atts(array('id' => '', 'style' => get_option('btb_style', 'default'), 'headline' => get_option('btb_shortcode_headline', __('Booking', 'bt-booking')), 'button_class' => get_option('btb_shortcode_buttonclass', ''), 'button_text' => get_option('btb_shortcode_buttontext', __('Book', 'bt-booking')), 'select_class' => get_option('btb_shortcode_timeselectorclass', ''), 'select_label' => get_option('btb_shortcode_timeselectortext', __('Dates', 'bt-booking')), 'select_layout' => get_option('btb_shortcode_timeselectorlayout', 'dropdown'), 'amount_input_class' => get_option('btb_shortcode_amount_class', ''), 'amount_input_type' => 'number', 'amount_input_surrounding' => get_option('btb_shortcode_amount_surrounding', ''), 'amount_input_label' => get_option('btb_shortcode_amount_label', __('People', 'bt-booking')), 'ind_req_label' => get_option('btb_shortcode_ind_req_label', __('Individual request', 'bt-booking')), 'ind_req_force' => get_option('btb_shortcode_force_ind_req', 0)), $atts);
     if (empty($a['id'])) {
         $current_post_type = get_post_type();
         if ($current_post_type == 'btb_event') {
             $a['id'] = get_the_ID();
         } elseif ($current_post_type == 'page') {
             $a['id'] = btb_get_event_id_by_desc_page(get_the_ID());
         }
     }
     if (empty($a['id'])) {
         return "<p>No ID given.</p>";
     }
     if ($master_instance) {
         $event = btb_get_event(intval($a['id']), OBJECT, 'display');
     } else {
         $event = btb_get_event_from_api(intval($a['id']), OBJECT, 'display');
     }
     if (!$event) {
         return '<p>' . esc_html__('Under the specified ID no event has been found.', 'bt-booking') . '</p>';
     }
     if ($event->post_type !== "btb_event") {
         return '<p>' . esc_html__('The content with the specified ID ist not an event.', 'bt-booking') . '</p>';
     }
     // requesting the event times from the database
     if ($master_instance) {
         $times = btb_get_times($event->ID, 'display', true);
         // calculate the free slots for each time
         if (!empty($times)) {
             foreach ($times as $key => $time) {
                 $time->calc_slots();
             }
         }
     } else {
         $times = btb_get_times_from_api($event->ID, 'display', true);
     }
     $venue = null;
     // apply the filter to generate the booking box output
     $out = apply_filters('btb_create_direct_booking_box', '', $event, $times, $venue, $a);
     // check if we should generate schema.org output, but only if PHP JSON extension is available.
     if (get_option('btb_struct_data_enabled', 0) == 1 && extension_loaded("json")) {
         if (empty($event->struct_data_type)) {
             $event->struct_data_type = get_option('btb_struct_data_default_type', 'event');
         }
         if (!$venue && $event->struct_data_type == 'event') {
             $venue = btb_get_venue($event->venue);
         }
         $out = apply_filters('btb_create_event_schema_org', $out, $event, $times, $venue);
     }
     return $out;
 }