lang);
        require_once './lang/' . $settings->lang . '.php';
        $lang = new Lang();
        $this->lang = $lang;
        $this->time = microtime(true);
        if ($header) {
            require_once './inc/header.php';
        }
        $this->conn = $settings->conn;
        $this->settings = $settings;
        $this->uuid_name_cache = array();
        $this->page = 1;
        if (isset($_GET['page'])) {
            $page = $_GET['page']; // user input
            if (filter_var($page, FILTER_VALIDATE_INT)) {
                $this->page = max(0, (int)$page);
            }
        }
        $this->name = $name;
        $this->type = null;
        $this->table = null;
        $this->title = null;
        $info = $this->type_info($name);
        $this->set_info($info);
        $this->permanent = array(
            'ban'  => $this->lang->page_perm_ban,
            'mute' => $this->lang->page_perm_mute,
            'warn' => $this->lang->page_perm_warn,
            'kick' => null,
        );
        $this->expired = array(
            'ban'  => $this->lang->page_expire_ban,
            'mute' => $this->lang->page_expire_mute,
            'warn' => $this->lang->page_expire,
            'kick' => null,
        );
        $this->expired_by = array(
            'ban'  => $this->lang->page_expire_ban_by,
            'mute' => $this->lang->page_expire_mute_by,
            'warn' => $this->lang->page_expire,
            'kick' => null,
        );
        if ($header) {
            $h = new Header($this);
            $this->header = $h;
            $h->print_header();
        }
        $this->table_headers_printed = false;
    }
    public function type_info($type) {
        $settings = $this->settings;
        switch ($type) {
            case "ban":
            case "bans":
                return array(
                    "type"  => "ban",
                    "table" => $settings->table['bans'],
                    "title" => $this->lang->page_title_ban,
                );
            case "mute":
            case "mutes":
                return array(
                    "type"  => "mute",
                    "table" => $settings->table['mutes'],
                    "title" => $this->lang->page_title_mute,
                );
            case "warn":
            case "warnings":
                return array(
                    "type"  => "warn",
                    "table" => $settings->table['warnings'],
                    "title" => $this->lang->page_title_warn,
                );
            case "kick":
            case "kicks":
                return array(
                    "type"  => "kick",
                    "table" => $settings->table['kicks'],
                    "title" => $this->lang->page_title_kick,
                );
            default:
                return array(
                    "type"  => null,
                    "table" => null,
                    "title" => null,
                );
        }
    }
    /**
     * @param $info
     */
    function set_info($info) {
        $this->type = $info['type'];
        $this->table = $info['table'];
        $this->title = $info['title'];
    }
    function run_query() {
        try {
            $table = $this->table;
            $active_query = $this->settings->active_query;
            $limit = $this->settings->limit_per_page;
            $offset = 0;
            if ($this->settings->show_pager) {
                $page = $this->page - 1;
                $offset = ($limit * $page);
            }
            $sel = $this->get_selection($table);
            $query = "SELECT $sel FROM $table $active_query GROUP BY $table.id ORDER BY time DESC LIMIT :limit OFFSET :offset";
            $st = $this->conn->prepare($query);
            $st->bindParam(':offset', $offset, PDO::PARAM_INT);
            $st->bindParam(':limit', $limit, PDO::PARAM_INT);
            $st->execute();
            return $st;
        } catch (PDOException $ex) {
            Settings::handle_error($this->settings, $ex);
        }
    }
    function get_selection($table) {
        // Under certain versions of PHP, there is a bug with BIT columns.
        // An empty string is returned no matter what the value is.
        // Workaround: cast to unsigned.
        $selection = "id,uuid,reason,banned_by_name,banned_by_uuid,time,until,CAST(active AS UNSIGNED) AS active";
        if ($table === $this->settings->table['warnings']) {
            $selection .= ",CAST(warned AS UNSIGNED) AS warned";
        }
        if ($table !== $this->settings->table['kicks']) {
            $selection .= ",removed_by_uuid,removed_by_name,removed_by_date";
        }
        return $selection;
    }
    /**
     * Returns HTML representing the Minecraft avatar for a specific name or UUID.
     * @param $name
     * @param $uuid
     * @param bool $name_under
     * @param string $name_repl
     * @return string
     */
    function get_avatar($name, $uuid, $name_under = true, $name_repl = null) {
        if ($name_under) {
            $name_under = $this->settings->avatar_names_below;
        }
        if (strlen($uuid) === 36 && $uuid[14] === '3') {
            // Avatars cannot be associated with offline mode UUIDs (version 3)
            $uuid = $name;
        }
        $src = str_replace('$NAME', $name, str_replace('$UUID', $uuid, $this->settings->avatar_source));
        if (in_array($name, $this->settings->console_aliases)) {
            $src = $this->settings->console_image;
            $name = $this->settings->console_name;
        }
        if ($name_repl !== null) {
            $name = $name_repl;
        }
        if ($name_under) {
            return "

$name
";
        }
        return " $name";
    }
    /**
     * Returns the banner name for a specific row in the database
     * using their UUID->name if possible, otherwise returns their last recorded name.
     * @param row
     * @return string
     */
    function get_banner_name($row) {
        $uuid = $row['banned_by_uuid'];
        $display_name = $row['banned_by_name'];
        $console_aliases = $this->settings->console_aliases;
        if (in_array($uuid, $console_aliases) || in_array($row['banned_by_name'], $console_aliases)) {
            return $this->settings->console_name;
        }
        $name = $this->get_name($uuid);
        if ($name !== null) {
            return $name;
        }
        return $this->clean($display_name);
    }
    /**
     * Returns the last name for a UUID, or null if their name is not recorded in the database.
     * @param string
     * @return null|string
     */
    function get_name($uuid) {
        if (in_array($uuid, $this->settings->console_aliases)) {
            return $this->settings->console_name;
        }
        if (array_key_exists($uuid, $this->uuid_name_cache)) return $this->uuid_name_cache[$uuid];
        $history = $this->settings->table['history'];
        $stmt = $this->conn->prepare("SELECT name FROM $history WHERE uuid=? ORDER BY date DESC LIMIT 1");
        if ($stmt->execute(array($uuid)) && $row = $stmt->fetch()) {
            $banner = $row['name'];
            $this->uuid_name_cache[$uuid] = $banner;
            return $banner;
        }
        $this->uuid_name_cache[$uuid] = null;
        return null;
    }
    /**
     * Prepares text to be displayed on the web interface.
     * Removes chat colours, replaces newlines with proper HTML, and sanitizes the text.
     * @param string
     * @return string|null
     */
    function clean($text) {
        if ($text === null) return null;
        if (strstr($text, "\xa7") || strstr($text, "&")) {
            $text = preg_replace("/(?i)(\xa7|&)[0-9A-FK-OR]/", "", $text);
        }
        $text = htmlspecialchars($text, ENT_QUOTES, "UTF-8");
        if (strstr($text, "\n")) {
            $text = preg_replace("/\n/", "
$name";
    }
    /**
     * Returns the banner name for a specific row in the database
     * using their UUID->name if possible, otherwise returns their last recorded name.
     * @param row
     * @return string
     */
    function get_banner_name($row) {
        $uuid = $row['banned_by_uuid'];
        $display_name = $row['banned_by_name'];
        $console_aliases = $this->settings->console_aliases;
        if (in_array($uuid, $console_aliases) || in_array($row['banned_by_name'], $console_aliases)) {
            return $this->settings->console_name;
        }
        $name = $this->get_name($uuid);
        if ($name !== null) {
            return $name;
        }
        return $this->clean($display_name);
    }
    /**
     * Returns the last name for a UUID, or null if their name is not recorded in the database.
     * @param string
     * @return null|string
     */
    function get_name($uuid) {
        if (in_array($uuid, $this->settings->console_aliases)) {
            return $this->settings->console_name;
        }
        if (array_key_exists($uuid, $this->uuid_name_cache)) return $this->uuid_name_cache[$uuid];
        $history = $this->settings->table['history'];
        $stmt = $this->conn->prepare("SELECT name FROM $history WHERE uuid=? ORDER BY date DESC LIMIT 1");
        if ($stmt->execute(array($uuid)) && $row = $stmt->fetch()) {
            $banner = $row['name'];
            $this->uuid_name_cache[$uuid] = $banner;
            return $banner;
        }
        $this->uuid_name_cache[$uuid] = null;
        return null;
    }
    /**
     * Prepares text to be displayed on the web interface.
     * Removes chat colours, replaces newlines with proper HTML, and sanitizes the text.
     * @param string
     * @return string|null
     */
    function clean($text) {
        if ($text === null) return null;
        if (strstr($text, "\xa7") || strstr($text, "&")) {
            $text = preg_replace("/(?i)(\xa7|&)[0-9A-FK-OR]/", "", $text);
        }
        $text = htmlspecialchars($text, ENT_QUOTES, "UTF-8");
        if (strstr($text, "\n")) {
            $text = preg_replace("/\n/", "
", $text);
        }
        return $text;
    }
    /**
     * Returns a string that shows the expiry date of a punishment.
     * If the punishment does not expire, it will be shown as permanent.
     * If the punishment has already expired, it will show as expired.
     * @param row
     * @return string
     */
    function expiry($row) {
        if ($this->type === "kick") {
            return "N/A";
        }
        if ($row['until'] <= 0) {
            $until = $this->permanent[$this->type];
        } else {
            $until = $this->millis_to_date($row['until']);
        }
        if ($this->active($row) === false) {
            $until .= ' ';
            $done = false;
            // Unbanned by $name
            $removed_by_uuid = $row['removed_by_uuid'];
            if ($removed_by_uuid !== null) {
                // Player has been unbanned
                // Check if uuid can be converted to name
                $name = $this->get_name($removed_by_uuid);
                if ($name === null) {
                    // Couldn't find name in history table, use removed_by_name instead
                    $name = $this->clean($row['removed_by_name']);
                }
                if ($name !== null) {
                    $until .= str_replace('$name', $name, $this->expired_by[$this->type]);
                    $done = true;
                }
            }
            if ($row['removed_by_name'] === "#expired") {
                $until .= $this->lang->page_expire;
                $done = true;
            }
            if ($done === false) {
                $until .= $this->expired[$this->type];
            }
        }
        return $until;
    }
    /**
     * Converts a timestamp (in milliseconds) to a date using the configured date format.
     * @param int
     * @return string
     */
    function millis_to_date($millis) {
        $ts = $millis / 1000;
        $result = strftime($this->settings->date_format, $ts);
        if ($result === "" || !is_string($result)) {
            // Fallback to date() if strftime() doesn't work
            return date("F j, Y, g:i A", $ts);
        }
        return $result;
    }
    function active($row, $field = 'active') {
        return (((int)$row[$field]) !== 0);
    }
    function print_title() {
        $title = $this->title;
        $name = $this->settings->name;
        if ($title === null) {
            echo "$name";
        } else {
            echo "$title - $name";
        }
    }
    function print_table_rows($row, $array, $print_headers = true) {
        if ($print_headers && !$this->table_headers_printed) {
            $headers = array_keys($array);
            $this->table_print_headers($headers);
            $this->table_headers_printed = true;
        }
        $id = $row['id'];
        $type = $this->type;
        echo "";
        foreach ($array as $header => $text) {
            $style = "";
            if ($header === $this->lang->bans_reason || $header === $this->lang->mutes_reason || $header === $this->lang->warns_reason || $header == $this->lang->kicks_reason) {
                $style = "style=\"width: 30%;\"";
                if ($text === "") {
                    $text = "-";
                }
            }
            $a = "a";
            if ($header === $this->lang->warns_receive) {
                $icon = ($text !== $this->lang->warns_no) ? "glyphicon-ok" : "glyphicon-remove";
                $a .= " class=\"glyphicon $icon\" aria-hidden=true";
                $text = "";
            }
            echo "| <$a href=\"info.php?type=$type&id=$id\">$text";
        }
        echo " | 
";
    }
    function table_print_headers($headers) {
        echo "";
        foreach ($headers as $header) {
            echo "| ";
        }
        echo "$header | 
";
    }
    function print_header($container_start = true) {
        $title = $this->title;
        if ($container_start) {
            echo '';
        }
        echo "
";
        if ($container_start) {
            echo '
';
        }
    }
    function print_check_form() {
        $table = $this->name;
        echo '
         
         ';
    }
    function print_pager($total = -1, $args = "", $prevargs = "") {
        if (!$this->settings->show_pager) return;
        $table = $this->table;
        $page = $this->name . ".php";
        if ($total === -1) {
            $result = $this->conn->query("SELECT COUNT(*) AS count FROM $table")->fetch(PDO::FETCH_ASSOC);
            $total = $result['count'];
        }
        $pages = (int)($total / $this->settings->limit_per_page) + 1;
        $cur = $this->page;
        $prev = $cur - 1;
        $next = $this->page + 1;
        $prev_active = ($cur > 1);
        $next_active = ($cur < $pages);
        $prev_class = "litebans-" . ($prev_active ? "pager-active" : "pager-inactive");
        $next_class = "litebans-" . ($next_active ? "pager-active" : "pager-inactive");
        $pager_prev = "";
        if ($prev_active) {
            $pager_prev = "
$pager_prev";
        }
        $pager_next = "";
        if ($next_active) {
            $pager_next = "
$pager_next";
        }
        $pager_count = '
' . $this->lang->page_page . ' ' . $cur . '/' . $pages . '
';
        echo "$pager_prev $pager_next $pager_count";
    }
    function print_footer($container_end = true) {
        if ($container_end) {
            echo "
';
    }
    function table_end($clicky = true) {
        echo '
';
        if ($clicky) {
            echo "";
        }
    }
    /**
     * lcfirst is only supported in PHP >= 5.3
     * @param $str
     * @return string
     */
    static function lc_first($str) {
        $str[0] = strtolower($str[0]);
        return (string)$str;
    }
}