function pect_get_google_timezone($lat, $lng)
{
    $url = "https://maps.googleapis.com/maps/api/timezone/json?location=" . $lat . "," . $lng . "&timestamp=" . time() . "&key=" . GOOGLE_API_TIMEZONE_KEY;
    $html = pect_cache_get_file('timezone', $url, PECT_CACHE_MAP_TIME, true, false);
    $json = json_decode($html, true);
    if (isset($json['status'])) {
        // We're allowed 2,500 requests per day. As this is now public on Virbank, this means
        // the number of requests shot up exponentially. This prevents over limit errors from
        // from being cached - the resulting calendar will still be cached so the address will
        // get tried again automatically within 24 hours assuming someone subcribed to that
        // calendar (and if they didn't we don't really care if it isn't up to date!)
        if ($json['status'] == 'OVER_QUERY_LIMIT') {
            $timezone = '';
            pect_cache_del_file('timezone', $url);
        } elseif (isset($json['timeZoneId'])) {
            $timezone = $json['timeZoneId'];
        } else {
            $timezone = '';
        }
    }
    return $timezone;
}
        if ($distanceFromCity == 1000) {
            $distanceFromCity = 99999;
            $countryFilter = $PECT_ISO_PKMN_3TO2[$country];
            $sortByDistance = 1;
        } else {
            $countryFilter = '';
            $sortByDistance = 0;
        }
        if (isset($_GET['nocache'])) {
            $searchUrl = pect_build_url($productType, $eventType, $city, $countryCode, $distanceFromCity, $daysBack, $daysForward, 100, $sortByDistance);
            $eventList = pect_get_events($searchUrl, $countryFilter);
            echo pect_events_to_ical($eventList, $city);
        } else {
            $url = str_replace('?t=1&', '?', "http://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}");
            $url = str_replace('&t=1', '', $url);
            echo pect_cache_get_file('calendar', $url . '&nocache', PECT_CACHE_CAL_TIME, true, false);
        }
    }
} elseif ($country == '' || $city == '') {
    pect_html_header();
    pect_html_menu($country);
    pect_html_footer();
} elseif (isset($_POST['country']) && isset($_POST['city'])) {
    $country = preg_replace('/[&=]/', '', substr($_POST['country'], 0, 3));
    $city = trim(preg_replace('/[&=]/', '', ucwords(strtolower($_POST['city']))));
    $productType = isset($_POST['tcg']) ? PECT_PRODUCT_TCG : 0;
    $productType |= isset($_POST['vgc']) ? PECT_PRODUCT_VGC : 0;
    $eventType = isset($_POST['premier']) ? PECT_EVENT_PREMIER : 0;
    $eventType |= isset($_POST['tournament']) ? PECT_EVENT_TOURNAMENT : 0;
    $eventType |= isset($_POST['league']) ? PECT_EVENT_LEAGUE : 0;
    $distanceFromCity = isset($_POST['distance']) ? $_POST['distance'] : -1;
function pect_get_events($searchUrl, $countryFilter)
{
    $baseHtml = str_get_html(pect_cache_get_file('search', $searchUrl, PECT_CACHE_SEARCH_TIME, true, false));
    if (!$baseHtml) {
        return;
    }
    $dataTable = $baseHtml->find('table[id=table-1]', 0);
    $eventList = array();
    $eventListText = array();
    $eventListId = 0;
    if (!$dataTable) {
        return;
    }
    foreach ($dataTable->find('tr') as $row) {
        if ($row->parent->tag == 'tbody') {
            $productTypeDesc = $row->find('td', 0)->find('span', 0)->innertext;
            $eventTypeDesc = $row->find('td', 1)->find('span', 0)->innertext;
            $eventUrl = PECT_BASE_URL . $row->find('td', 2)->find('a', 0)->href;
            $productType = 0;
            if ($productTypeDesc == 'ALL' || $productTypeDesc == 'TCG') {
                $productType |= PECT_PRODUCT_TCG;
            }
            if ($productTypeDesc == 'ALL' || $productTypeDesc == 'VG') {
                $productType |= PECT_PRODUCT_VGC;
            }
            if ($productTypeDesc == 'Video Game') {
                $productType |= PECT_PRODUCT_VGC;
            }
            if (substr($productTypeDesc, -3, 3) == 'TCG') {
                $productType |= PECT_PRODUCT_TCG;
            }
            // The event type is prefixed with a space, and there aren't any that use multiple words at the moment,
            // so we'll just remove any whitepsace from the string before we check it.
            $eventType = 0;
            $eventTypeDesc = str_replace(' ', '', $eventTypeDesc);
            $eventTypeDesc = preg_replace('/.*League/', 'League', $eventTypeDesc);
            if ($eventTypeDesc == 'League') {
                $eventType |= PECT_EVENT_LEAGUE;
            }
            if ($eventTypeDesc == 'Tournament') {
                $eventType |= PECT_EVENT_TOURNAMENT;
            }
            if ($eventTypeDesc == 'Premier') {
                $eventType |= PECT_EVENT_PREMIER;
            }
            $eventCache = pect_cache_get_file('events', $eventUrl, PECT_CACHE_ITEM_TIME, true, false, 'ical');
            $skipCountryEvent = false;
            if (!$eventCache) {
                $eventHtml = str_get_html(pect_cache_get_file('events', $eventUrl, PECT_CACHE_ITEM_TIME));
                $eventLocationName = '';
                $eventAddressLine1 = '';
                $eventAddressLine2 = '';
                $eventCity = '';
                $eventState = '';
                $eventPostcode = '';
                $eventCountry = '';
                $eventDates = array();
                $eventLatitude = null;
                $eventLongitude = null;
                if ($eventHtml != null) {
                    if ($eventType & PECT_EVENT_LEAGUE) {
                        $eventLocationData = $eventHtml->find('dl[class=verysimpleDL2]', 0);
                        $eventLocationName = str_replace('<label></label>', '', $eventLocationData->find('dd', 0)->plaintext);
                        $eventAddressLine1 = $eventLocationData->find('dd', 1)->plaintext;
                        $eventAddressLine2 = $eventLocationData->find('dd', 2)->plaintext;
                        $eventCity = $eventLocationData->find('dd', 3)->plaintext;
                        $eventState = $eventLocationData->find('dd', 4)->plaintext;
                        $eventPostcode = $eventLocationData->find('dd', 5)->plaintext;
                        $eventCountry = $eventLocationData->find('dd', 6)->plaintext;
                        $eventOrgData = $eventHtml->find('div[id=league-details-contact]', 0);
                        $eventOrganiser = '';
                        $eventContactNo = $eventOrgData->find('dd', 1)->plaintext;
                        $eventWebsite = $eventOrgData->find('dd', 2)->plaintext;
                        $eventDescription = '';
                        // Now we have to extract events. The upcoming events only shows the next three, so we'll go straight
                        // to the calendar instead. The calendar uses a different class to highlight days with events on, so
                        // we'll search for those cells.
                        $eventDateData = $eventHtml->find('div[class=right-content]', 0);
                        // First we need to process the top month, then the second month.
                        $eventDatesId = 0;
                        for ($x = 0; $x < 2; $x++) {
                            $eventMonth = $eventDateData->find('h6[class=cufon]', $x)->plaintext;
                            $eventCalendar = $eventDateData->find('table', $x);
                            foreach ($eventCalendar->find('td[class=calendar-playtime-season]') as $eventCalendarDay) {
                                $eventDay = $eventCalendarDay->plaintext;
                                $eventDate = $eventMonth . ' ' . $eventDay;
                                $eventNameFull = $eventCalendarDay->getAttribute('title');
                                $eventName = preg_replace('/\\(([^\\)]*)\\).*/', '\\1', $eventNameFull);
                                $eventRegistrationTime = preg_replace('/.*\\(\\(([^\\)]*)\\).*/', '\\1', $eventNameFull);
                                $eventDates[$eventDatesId] = array();
                                $eventDates[$eventDatesId][0] = trim(str_replace('<label></label>', '', $eventName));
                                $eventDates[$eventDatesId][1] = '';
                                $eventDates[$eventDatesId][2] = '';
                                $eventDates[$eventDatesId][3] = trim(str_replace('<label></label>', '', $eventDate));
                                $eventDates[$eventDatesId][4] = trim(preg_replace('/(.*) - .*/', '\\1', $eventRegistrationTime));
                                $eventDates[$eventDatesId][5] = trim(preg_replace('/.* - (.*)/', '\\1', $eventRegistrationTime));
                                $eventDates[$eventDatesId][6] = '';
                                $eventDates[$eventDatesId][7] = '';
                                $eventDatesId++;
                            }
                        }
                    } elseif ($eventType & PECT_EVENT_TOURNAMENT || $eventType & PECT_EVENT_PREMIER) {
                        $eventLocationData = $eventHtml->find('div[class=pane]', 0)->find('form[class=list-text-only]', 2)->find('div[class=bot]', 0)->find('ol', 0);
                        // We need to strip the labels out of the DOM to just get the correct address data.
                        for ($x = 0; $x < 7; $x++) {
                            $eventLocationData->find('label', $x)->innertext = '';
                        }
                        $eventLocationName = str_replace('<label></label>', '', $eventLocationData->find('li', 0)->innertext);
                        $eventAddressLine1 = $eventLocationData->find('li', 1)->innertext;
                        $eventAddressLine2 = $eventLocationData->find('li', 2)->innertext;
                        $eventCity = $eventLocationData->find('li', 3)->innertext;
                        $eventState = $eventLocationData->find('li', 4)->innertext;
                        $eventPostcode = $eventLocationData->find('li', 5)->innertext;
                        $eventCountry = $eventLocationData->find('li', 6)->innertext;
                        // If there is a map link, we'll pull the geo coordinates from there rather than make
                        // a call to Google's mapping API.
                        $eventMapUrl = $eventLocationData->find('li', 7)->find('a', 0)->href;
                        $eventMapCoords = preg_replace('/.*q=([0-9\\-., ]*) \\(.*/', '\\1', $eventMapUrl);
                        $eventLatitude = preg_replace('/([^,]*).*/', '\\1', $eventMapCoords);
                        $eventLongitude = preg_replace('/.*, (.*)/', '\\1', $eventMapCoords);
                        // Now we extract the event data.
                        $eventDateData = $eventHtml->find('div[class=pane]', 0)->find('form[class=list-text-only]', 0)->find('div[class=bot]', 0)->find('ol', 0);
                        for ($x = 0; $x < 8; $x++) {
                            $eventDateData->find('label', $x)->innertext = '';
                        }
                        $eventName = $eventDateData->find('li', 0)->innertext;
                        $eventId = $eventDateData->find('li', 1)->innertext;
                        $eventCategory = $eventDateData->find('li', 2)->innertext;
                        $eventDate = $eventDateData->find('li', 3)->innertext;
                        $eventRegistrationTime = $eventDateData->find('li', 4)->innertext;
                        $eventPremierEvent = $eventDateData->find('li', 6)->plaintext;
                        $eventStatus = $eventDateData->find('li', 7)->innertext;
                        // We also grab the organiser information so we can display it in the calendar.
                        $eventOrgData = $eventHtml->find('div[class=pane]', 0)->find('form[class=list-text-only]', 1)->find('div[class=bot]', 0)->find('ol', 0);
                        $eventOrganiser = '';
                        $eventContactNo = '';
                        $eventWebsite = '';
                        // Not all the fields appear all the time, so we need to iterate through each li
                        // item and check the label associated with it to determine the data content.
                        foreach ($eventOrgData->find('li') as $eventOrgLine) {
                            if ($eventOrgLine->find('label', 0)->innertext == 'Organizer Name') {
                                $eventOrganiser = $eventOrgLine->find('span', 0)->innertext;
                            } elseif ($eventOrgLine->find('label', 0)->innertext == 'Organizer Phone') {
                                $eventContactNo = preg_replace('/<label>.*<\\/label>(.*)/', '\\1', $eventOrgData->find('li', 1)->innertext);
                            }
                        }
                        // Finally, we grab the event description, if one exists.
                        $eventDescData = $eventHtml->find('div[class=pane]', 0)->find('form[class=list-text-only]', 2)->find('div[class=bot]', 1)->find('ol', 0);
                        $eventDescription = '';
                        foreach ($eventDescData->find('li') as $eventDescLine) {
                            if ($eventDescLine->find('label', 0)->innertext == 'Details') {
                                foreach ($eventDescLine->find('p') as $eventParagraph) {
                                    if ($eventParagraph->innertext != '') {
                                        $eventDescription .= $eventParagraph->innertext . "\\n\\n";
                                    }
                                }
                            }
                        }
                        $eventDates[0] = array();
                        $eventDates[0][0] = trim(str_replace('<label></label>', '', $eventName));
                        $eventDates[0][1] = trim(str_replace('<label></label>', '', $eventId));
                        $eventDates[0][2] = trim(str_replace('<label></label>', '', $eventCategory));
                        $eventDates[0][3] = trim(str_replace('<label></label>', '', $eventDate));
                        $eventDates[0][4] = trim(preg_replace('/(.*) to .*/', '\\1', str_replace('<label></label>', '', $eventRegistrationTime)));
                        $eventDates[0][5] = trim(preg_replace('/.* to (.*)/', '\\1', str_replace('<label></label>', '', $eventRegistrationTime)));
                        $eventDates[0][6] = trim($eventPremierEvent);
                        $eventDates[0][7] = trim(str_replace('<label></label>', '', $eventStatus));
                    }
                }
                $eventList[0] = $productType;
                $eventList[1] = $eventType;
                $eventList[2] = trim($eventUrl);
                $eventList[3] = trim($eventLocationName);
                $eventList[4] = trim($eventAddressLine1);
                $eventList[5] = trim($eventAddressLine2);
                $eventList[6] = trim($eventCity);
                $eventList[7] = trim($eventState);
                $eventList[8] = trim($eventPostcode);
                $eventList[9] = trim($eventCountry);
                $eventList[10] = $eventDates;
                $eventList[11] = trim($eventOrganiser);
                $eventList[12] = trim($eventContactNo);
                $eventList[13] = trim($eventWebsite);
                $eventList[14] = $eventLatitude;
                $eventList[15] = $eventLongitude;
                $eventList[16] = $eventDescription;
                $timezones = array();
                $tzid = 0;
                $id = 0;
                $icalEvents = '';
                $icalTimezones = '';
                foreach ($eventList[10] as $eventData) {
                    $startDate = strtotime($eventData[3] . ' ' . $eventData[4]);
                    $endDate = strtotime($eventData[3] . ' ' . $eventData[5]);
                    $address = $eventList[4] . ', ' . $eventList[5] . ', ' . $eventList[6] . ', ' . $eventList[7] . ', ' . $eventList[8] . ', ' . $eventList[9];
                    $address = str_replace(', &nbsp;', '', $address);
                    $address = str_replace('<label></label>', '', $address);
                    $address = str_replace(', ,', ',', $address);
                    $address = str_replace(', ,', ',', $address);
                    $address = str_replace(',', '\\,', $address);
                    $address = str_replace('&amp;', '&', $address);
                    $address = str_replace(';', '\\;', $address);
                    if ($eventList[14] != '' && $eventList[15] != '') {
                        $geoCoords = pect_get_google_coordinates('', $eventList[14], $eventList[15]);
                    } else {
                        $geoCoords = pect_get_google_coordinates($address);
                    }
                    // If we weren't able to geolocate the address, then we copy across the event
                    // coordinates (if they exist, they default to null if they don't anyway) and
                    // set the address to our previously parsed address. If we could, we apply
                    // some formatting to it for iCal specs and then save it back to the $geoCoords
                    // array.
                    if ($geoCoords[0] == null) {
                        $geoCoords[0] = $eventList[14];
                        $geoCoords[1] = $eventList[15];
                        $geoCoords[2] = ucwords($eventList[3] . ', ' . $address);
                        $geoCoords[3] = '';
                    } else {
                        $geoCoords[2] = ucwords($eventList[3]) . ', ' . $geoCoords[2];
                    }
                    $geoCoords[2] = str_replace(',', '\\,', $geoCoords[2]);
                    $geoCoords[2] = str_replace('&amp;', '&', $geoCoords[2]);
                    $geoCoords[2] = str_replace(';', '\\;', $geoCoords[2]);
                    $skipCountryEvent = $countryFilter == '' ? false : true;
                    if ($skipCountryEvent && $geoCoords[3] == $countryFilter) {
                        $skipCountryEvent = false;
                    }
                    // Now if we didn't have coordinates, we weren't able to derive a timezone. As such
                    // we'll default to the first timezone in the calendar if available, or leave it
                    // blank if there isn't one. No timezone means the iCal client will interpret the
                    // time based on it's own local timezone (which should in theory be the right one!)
                    if ($geoCoords[0] == null || $geoCoords[1] == null) {
                        if (isset($timezones[0])) {
                            $timezone = $timezones[0];
                        } else {
                            $timezone = '';
                        }
                    } else {
                        $timezone = pect_get_google_timezone($geoCoords[0], $geoCoords[1]);
                        if (!in_array($timezone, $timezones)) {
                            $tzdata = pect_cache_get_tz_data($timezone);
                            if (strpos($tzdata, 'DOCTYPE HTML') === false) {
                                $timezones[$tzid++] = $timezone;
                                $icalTimezones .= pect_cache_get_tz_data($timezone);
                            }
                        }
                    }
                    if ($timezone == '') {
                        $tzData = '';
                    } else {
                        $tzData = ';TZID=' . $timezone;
                    }
                    $summary = $eventData[0];
                    $summary = str_replace(";", '\\;', $summary);
                    $summary = str_replace("\\", '\\', $summary);
                    $summary = str_replace(",", '\\,', $summary);
                    $prefix = '';
                    $suffix = '';
                    if ($eventList[0] & PECT_PRODUCT_VGC) {
                        $prefix = '[VG] ';
                    }
                    if ($eventList[0] & PECT_PRODUCT_TCG) {
                        if ($prefix == '') {
                            $prefix = '[TCG] ';
                        } else {
                            $prefix = '[VG/TCG] ';
                        }
                    }
                    if ($eventList[1] & PECT_EVENT_LEAGUE) {
                        $suffix = ' (Pokemon League)';
                    }
                    if ($eventList[1] & PECT_EVENT_TOURNAMENT) {
                        $suffix = ' (Tournament)';
                    }
                    if ($eventList[1] & PECT_EVENT_PREMIER) {
                        $suffix = ' (Premier Event)';
                    }
                    if ($eventList[1] & PECT_EVENT_LEAGUE) {
                        $uid = preg_replace('/.*\\/leagues\\/([0-9]*)\\//', '\\1', $eventList[2]);
                        $uid = date('y\\-m\\-d', $startDate) . '-' . $uid;
                    } else {
                        $uid = preg_replace('/.*\\/([0-9][0-9]-[0-9][0-9]-[0-9]*)\\//', '\\1', $eventList[2]);
                    }
                    $uid .= '@codearoundcorners.com';
                    $notes = '';
                    if ($eventList[11] != '') {
                        $notes .= ' * Organiser - ' . $eventList[11] . "\\n\r\n";
                    }
                    if ($eventList[12] != '') {
                        $notes .= ' * Phone - ' . pect_format_phone($eventList[12]) . "\\n\r\n";
                    }
                    if ($eventList[13] != '') {
                        $notes .= ' * Website - ' . $eventList[13] . "\\n\r\n";
                    }
                    if ($notes != '' || $eventList[16] != '') {
                        $eventText = str_replace("<br />", "\\n", $eventList[16]);
                        $eventText = str_replace("&#39;", '\'', $eventText);
                        $eventText = str_replace(";", '\\;', $eventText);
                        $eventText = str_replace("\\", '\\', $eventText);
                        $eventText = str_replace(",", '\\,', $eventText);
                        $eventText = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $eventText);
                        $notes = "Additional information for this event:\\n\r\n" . $notes . " \\n" . $eventText . "\r\n";
                    }
                    $icalEvents .= "BEGIN:VEVENT\r\n";
                    $icalEvents .= "UID:" . $uid . "\r\n";
                    $icalEvents .= "LAST-MODIFIED:" . pect_cache_get_last_modified('events', $eventList[2]) . "\r\n";
                    $icalEvents .= "DTSTAMP:" . date('Ymd\\THis', $startDate) . "\r\n";
                    $icalEvents .= "SUMMARY:" . $prefix . $summary . $suffix . "\r\n";
                    $icalEvents .= "DTSTART" . $tzData . ":" . date('Ymd\\THis', $startDate) . "\r\n";
                    $icalEvents .= "DTEND" . $tzData . ":" . date('Ymd\\THis', $endDate) . "\r\n";
                    $icalEvents .= "URL:" . $eventList[2] . "\r\n";
                    $icalEvents .= "LOCATION:" . $geoCoords[2] . "\r\n";
                    if ($geoCoords[0] != null && $geoCoords[1] != null) {
                        $icalEvents .= "GEO:" . $geoCoords[0] . ";" . $geoCoords[1] . "\r\n";
                    }
                    if ($notes != '') {
                        $icalEvents .= "DESCRIPTION:" . $notes;
                    }
                    $icalEvents .= "END:VEVENT\r\n";
                }
                $icalEvents .= "COUNTRY-CODE:" . $geoCoords[3];
                if ($timezone != '') {
                    pect_cache_put_file($icalTimezones . $icalEvents, 'events', $eventUrl, 'ical');
                }
                if (!$skipCountryEvent) {
                    $eventListText[$eventListId] = array();
                    $eventListText[$eventListId][0] = $icalTimezones;
                    $eventListText[$eventListId][1] = $icalEvents;
                }
            } else {
                $splitPos1 = strpos($eventCache, 'BEGIN:VEVENT');
                $splitPos2 = strpos($eventCache, 'COUNTRY-CODE:');
                $skipCountryEvent = $countryFilter == '' ? false : true;
                if ($skipCountryEvent) {
                    $countryCode = substr($eventCache, $splitPos2, strlen($eventCache) - $splitPos2);
                    $countryCode = substr($countryCode, -2, 2);
                    if ($countryCode == $countryFilter) {
                        $skipCountryEvent = false;
                    }
                }
                if (!$skipCountryEvent) {
                    $eventListText[$eventListId] = array();
                    $eventListText[$eventListId][0] = substr($eventCache, 0, $splitPos1);
                    $eventListText[$eventListId][1] = substr($eventCache, $splitPos1, $splitPos2 - $splitPos1);
                }
            }
            if (!$skipCountryEvent) {
                $eventListId++;
            }
        }
    }
    return $eventListText;
}