// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE

using System;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics;
using osu.Framework.IO.Stores;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Caching;

namespace osu.Game.Graphics
{
    public class SpriteIcon : CompositeDrawable
    {
        private readonly Sprite spriteShadow;
        private readonly Sprite spriteMain;

        private Cached layout = new Cached();
        private readonly Container shadowVisibility;

        public SpriteIcon()
        {
            InternalChildren = new Drawable[]
            {
                shadowVisibility = new Container
                {
                    Anchor = Anchor.Centre,
                    Origin = Anchor.Centre,
                    RelativeSizeAxes = Axes.Both,
                    Child = spriteShadow = new Sprite
                    {
                        Anchor = Anchor.Centre,
                        Origin = Anchor.Centre,
                        RelativeSizeAxes = Axes.Both,
                        FillMode = FillMode.Fit,
                        Y = 2,
                        Colour = new Color4(0f, 0f, 0f, 0.2f),
                    },
                    Alpha = 0,
                },
                spriteMain = new Sprite
                {
                    Anchor = Anchor.Centre,
                    Origin = Anchor.Centre,
                    RelativeSizeAxes = Axes.Both,
                    FillMode = FillMode.Fit
                },
            };
        }

        private FontStore store;

        [BackgroundDependencyLoader]
        private void load(FontStore store)
        {
            this.store = store;
        }

        protected override void LoadComplete()
        {
            base.LoadComplete();

            updateTexture();
        }

        private void updateTexture()
        {
            var texture = store?.Get(((char)icon).ToString());

            spriteMain.Texture = texture;
            spriteShadow.Texture = texture;

            if (Size == Vector2.Zero)
                Size = new Vector2(texture?.DisplayWidth ?? 0, texture?.DisplayHeight ?? 0);
        }

        public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
        {
            if ((invalidation & Invalidation.Colour) > 0 && Shadow)
                layout.Invalidate();
            return base.Invalidate(invalidation, source, shallPropagate);
        }

        protected override void Update()
        {
            if (!layout.IsValid)
            {
                //adjust shadow alpha based on highest component intensity to avoid muddy display of darker text.
                //squared result for quadratic fall-off seems to give the best result.
                var avgColour = (Color4)DrawInfo.Colour.AverageColour;

                spriteShadow.Alpha = (float)Math.Pow(Math.Max(Math.Max(avgColour.R, avgColour.G), avgColour.B), 2);

                layout.Validate();
            }
        }

        public bool Shadow
        {
            get { return spriteShadow.IsPresent; }
            set
            {
                shadowVisibility.Alpha = value ? 1 : 0;
            }
        }

        private FontAwesome icon;

        public FontAwesome Icon
        {
            get
            {
                return icon;
            }

            set
            {
                if (icon == value) return;

                icon = value;
                if (IsLoaded)
                    updateTexture();
            }
        }
    }

    public enum FontAwesome
    {
        fa_500px = 0xf26e,
        fa_address_book = 0xf2b9,
        fa_address_book_o = 0xf2ba,
        fa_address_card = 0xf2bb,
        fa_address_card_o = 0xf2bc,
        fa_adjust = 0xf042,
        fa_adn = 0xf170,
        fa_align_center = 0xf037,
        fa_align_justify = 0xf039,
        fa_align_left = 0xf036,
        fa_align_right = 0xf038,
        fa_amazon = 0xf270,
        fa_ambulance = 0xf0f9,
        fa_american_sign_language_interpreting = 0xf2a3,
        fa_anchor = 0xf13d,
        fa_android = 0xf17b,
        fa_angellist = 0xf209,
        fa_angle_double_down = 0xf103,
        fa_angle_double_left = 0xf100,
        fa_angle_double_right = 0xf101,
        fa_angle_double_up = 0xf102,
        fa_angle_down = 0xf107,
        fa_angle_left = 0xf104,
        fa_angle_right = 0xf105,
        fa_angle_up = 0xf106,
        fa_apple = 0xf179,
        fa_archive = 0xf187,
        fa_area_chart = 0xf1fe,
        fa_arrow_circle_down = 0xf0ab,
        fa_arrow_circle_left = 0xf0a8,
        fa_arrow_circle_o_down = 0xf01a,
        fa_arrow_circle_o_left = 0xf190,
        fa_arrow_circle_o_right = 0xf18e,
        fa_arrow_circle_o_up = 0xf01b,
        fa_arrow_circle_right = 0xf0a9,
        fa_arrow_circle_up = 0xf0aa,
        fa_arrow_down = 0xf063,
        fa_arrow_left = 0xf060,
        fa_arrow_right = 0xf061,
        fa_arrow_up = 0xf062,
        fa_arrows = 0xf047,
        fa_arrows_alt = 0xf0b2,
        fa_arrows_h = 0xf07e,
        fa_arrows_v = 0xf07d,
        fa_asl_interpreting = 0xf2a3,
        fa_assistive_listening_systems = 0xf2a2,
        fa_asterisk = 0xf069,
        fa_at = 0xf1fa,
        fa_audio_description = 0xf29e,
        fa_automobile = 0xf1b9,
        fa_backward = 0xf04a,
        fa_balance_scale = 0xf24e,
        fa_ban = 0xf05e,
        fa_bandcamp = 0xf2d5,
        fa_bank = 0xf19c,
        fa_bar_chart = 0xf080,
        fa_bar_chart_o = 0xf080,
        fa_barcode = 0xf02a,
        fa_bars = 0xf0c9,
        fa_bath = 0xf2cd,
        fa_bathtub = 0xf2cd,
        fa_battery = 0xf240,
        fa_battery_0 = 0xf244,
        fa_battery_1 = 0xf243,
        fa_battery_2 = 0xf242,
        fa_battery_3 = 0xf241,
        fa_battery_4 = 0xf240,
        fa_battery_empty = 0xf244,
        fa_battery_full = 0xf240,
        fa_battery_half = 0xf242,
        fa_battery_quarter = 0xf243,
        fa_battery_three_quarters = 0xf241,
        fa_bed = 0xf236,
        fa_beer = 0xf0fc,
        fa_behance = 0xf1b4,
        fa_behance_square = 0xf1b5,
        fa_bell = 0xf0f3,
        fa_bell_o = 0xf0a2,
        fa_bell_slash = 0xf1f6,
        fa_bell_slash_o = 0xf1f7,
        fa_bicycle = 0xf206,
        fa_binoculars = 0xf1e5,
        fa_birthday_cake = 0xf1fd,
        fa_bitbucket = 0xf171,
        fa_bitbucket_square = 0xf172,
        fa_bitcoin = 0xf15a,
        fa_black_tie = 0xf27e,
        fa_blind = 0xf29d,
        fa_bluetooth = 0xf293,
        fa_bluetooth_b = 0xf294,
        fa_bold = 0xf032,
        fa_bolt = 0xf0e7,
        fa_bomb = 0xf1e2,
        fa_book = 0xf02d,
        fa_bookmark = 0xf02e,
        fa_bookmark_o = 0xf097,
        fa_braille = 0xf2a1,
        fa_briefcase = 0xf0b1,
        fa_btc = 0xf15a,
        fa_bug = 0xf188,
        fa_building = 0xf1ad,
        fa_building_o = 0xf0f7,
        fa_bullhorn = 0xf0a1,
        fa_bullseye = 0xf140,
        fa_bus = 0xf207,
        fa_buysellads = 0xf20d,
        fa_cab = 0xf1ba,
        fa_calculator = 0xf1ec,
        fa_calendar = 0xf073,
        fa_calendar_check_o = 0xf274,
        fa_calendar_minus_o = 0xf272,
        fa_calendar_o = 0xf133,
        fa_calendar_plus_o = 0xf271,
        fa_calendar_times_o = 0xf273,
        fa_camera = 0xf030,
        fa_camera_retro = 0xf083,
        fa_car = 0xf1b9,
        fa_caret_down = 0xf0d7,
        fa_caret_left = 0xf0d9,
        fa_caret_right = 0xf0da,
        fa_caret_square_o_down = 0xf150,
        fa_caret_square_o_left = 0xf191,
        fa_caret_square_o_right = 0xf152,
        fa_caret_square_o_up = 0xf151,
        fa_caret_up = 0xf0d8,
        fa_cart_arrow_down = 0xf218,
        fa_cart_plus = 0xf217,
        fa_cc = 0xf20a,
        fa_cc_amex = 0xf1f3,
        fa_cc_diners_club = 0xf24c,
        fa_cc_discover = 0xf1f2,
        fa_cc_jcb = 0xf24b,
        fa_cc_mastercard = 0xf1f1,
        fa_cc_paypal = 0xf1f4,
        fa_cc_stripe = 0xf1f5,
        fa_cc_visa = 0xf1f0,
        fa_certificate = 0xf0a3,
        fa_chain = 0xf0c1,
        fa_chain_broken = 0xf127,
        fa_check = 0xf00c,
        fa_check_circle = 0xf058,
        fa_check_circle_o = 0xf05d,
        fa_check_square = 0xf14a,
        fa_check_square_o = 0xf046,
        fa_chevron_circle_down = 0xf13a,
        fa_chevron_circle_left = 0xf137,
        fa_chevron_circle_right = 0xf138,
        fa_chevron_circle_up = 0xf139,
        fa_chevron_down = 0xf078,
        fa_chevron_left = 0xf053,
        fa_chevron_right = 0xf054,
        fa_chevron_up = 0xf077,
        fa_child = 0xf1ae,
        fa_chrome = 0xf268,
        fa_circle = 0xf111,
        fa_circle_o = 0xf10c,
        fa_circle_o_notch = 0xf1ce,
        fa_circle_thin = 0xf1db,
        fa_clipboard = 0xf0ea,
        fa_clock_o = 0xf017,
        fa_clone = 0xf24d,
        fa_close = 0xf00d,
        fa_cloud = 0xf0c2,
        fa_cloud_download = 0xf0ed,
        fa_cloud_upload = 0xf0ee,
        fa_cny = 0xf157,
        fa_code = 0xf121,
        fa_code_fork = 0xf126,
        fa_codepen = 0xf1cb,
        fa_codiepie = 0xf284,
        fa_coffee = 0xf0f4,
        fa_cog = 0xf013,
        fa_cogs = 0xf085,
        fa_columns = 0xf0db,
        fa_comment = 0xf075,
        fa_comment_o = 0xf0e5,
        fa_commenting = 0xf27a,
        fa_commenting_o = 0xf27b,
        fa_comments = 0xf086,
        fa_comments_o = 0xf0e6,
        fa_compass = 0xf14e,
        fa_compress = 0xf066,
        fa_connectdevelop = 0xf20e,
        fa_contao = 0xf26d,
        fa_copy = 0xf0c5,
        fa_copyright = 0xf1f9,
        fa_creative_commons = 0xf25e,
        fa_credit_card = 0xf09d,
        fa_credit_card_alt = 0xf283,
        fa_crop = 0xf125,
        fa_crosshairs = 0xf05b,
        fa_css3 = 0xf13c,
        fa_cube = 0xf1b2,
        fa_cubes = 0xf1b3,
        fa_cut = 0xf0c4,
        fa_cutlery = 0xf0f5,
        fa_dashboard = 0xf0e4,
        fa_dashcube = 0xf210,
        fa_database = 0xf1c0,
        fa_deaf = 0xf2a4,
        fa_deafness = 0xf2a4,
        fa_dedent = 0xf03b,
        fa_delicious = 0xf1a5,
        fa_desktop = 0xf108,
        fa_deviantart = 0xf1bd,
        fa_diamond = 0xf219,
        fa_digg = 0xf1a6,
        fa_dollar = 0xf155,
        fa_dot_circle_o = 0xf192,
        fa_download = 0xf019,
        fa_dribbble = 0xf17d,
        fa_drivers_license = 0xf2c2,
        fa_drivers_license_o = 0xf2c3,
        fa_dropbox = 0xf16b,
        fa_drupal = 0xf1a9,
        fa_edge = 0xf282,
        fa_edit = 0xf044,
        fa_eercast = 0xf2da,
        fa_eject = 0xf052,
        fa_ellipsis_h = 0xf141,
        fa_ellipsis_v = 0xf142,
        fa_empire = 0xf1d1,
        fa_envelope = 0xf0e0,
        fa_envelope_o = 0xf003,
        fa_envelope_open = 0xf2b6,
        fa_envelope_open_o = 0xf2b7,
        fa_envelope_square = 0xf199,
        fa_envira = 0xf299,
        fa_eraser = 0xf12d,
        fa_etsy = 0xf2d7,
        fa_eur = 0xf153,
        fa_euro = 0xf153,
        fa_exchange = 0xf0ec,
        fa_exclamation = 0xf12a,
        fa_exclamation_circle = 0xf06a,
        fa_exclamation_triangle = 0xf071,
        fa_expand = 0xf065,
        fa_expeditedssl = 0xf23e,
        fa_external_link = 0xf08e,
        fa_external_link_square = 0xf14c,
        fa_eye = 0xf06e,
        fa_eye_slash = 0xf070,
        fa_eyedropper = 0xf1fb,
        fa_fa = 0xf2b4,
        fa_facebook = 0xf09a,
        fa_facebook_f = 0xf09a,
        fa_facebook_official = 0xf230,
        fa_facebook_square = 0xf082,
        fa_fast_backward = 0xf049,
        fa_fast_forward = 0xf050,
        fa_fax = 0xf1ac,
        fa_feed = 0xf09e,
        fa_female = 0xf182,
        fa_fighter_jet = 0xf0fb,
        fa_file = 0xf15b,
        fa_file_archive_o = 0xf1c6,
        fa_file_audio_o = 0xf1c7,
        fa_file_code_o = 0xf1c9,
        fa_file_excel_o = 0xf1c3,
        fa_file_image_o = 0xf1c5,
        fa_file_movie_o = 0xf1c8,
        fa_file_o = 0xf016,
        fa_file_pdf_o = 0xf1c1,
        fa_file_photo_o = 0xf1c5,
        fa_file_picture_o = 0xf1c5,
        fa_file_powerpoint_o = 0xf1c4,
        fa_file_sound_o = 0xf1c7,
        fa_file_text = 0xf15c,
        fa_file_text_o = 0xf0f6,
        fa_file_video_o = 0xf1c8,
        fa_file_word_o = 0xf1c2,
        fa_file_zip_o = 0xf1c6,
        fa_files_o = 0xf0c5,
        fa_film = 0xf008,
        fa_filter = 0xf0b0,
        fa_fire = 0xf06d,
        fa_fire_extinguisher = 0xf134,
        fa_firefox = 0xf269,
        fa_first_order = 0xf2b0,
        fa_flag = 0xf024,
        fa_flag_checkered = 0xf11e,
        fa_flag_o = 0xf11d,
        fa_flash = 0xf0e7,
        fa_flask = 0xf0c3,
        fa_flickr = 0xf16e,
        fa_floppy_o = 0xf0c7,
        fa_folder = 0xf07b,
        fa_folder_o = 0xf114,
        fa_folder_open = 0xf07c,
        fa_folder_open_o = 0xf115,
        fa_font = 0xf031,
        fa_font_awesome = 0xf2b4,
        fa_fonticons = 0xf280,
        fa_fort_awesome = 0xf286,
        fa_forumbee = 0xf211,
        fa_forward = 0xf04e,
        fa_foursquare = 0xf180,
        fa_free_code_camp = 0xf2c5,
        fa_frown_o = 0xf119,
        fa_futbol_o = 0xf1e3,
        fa_gamepad = 0xf11b,
        fa_gavel = 0xf0e3,
        fa_gbp = 0xf154,
        fa_ge = 0xf1d1,
        fa_gear = 0xf013,
        fa_gears = 0xf085,
        fa_genderless = 0xf22d,
        fa_get_pocket = 0xf265,
        fa_gg = 0xf260,
        fa_gg_circle = 0xf261,
        fa_gift = 0xf06b,
        fa_git = 0xf1d3,
        fa_git_square = 0xf1d2,
        fa_github = 0xf09b,
        fa_github_alt = 0xf113,
        fa_github_square = 0xf092,
        fa_gitlab = 0xf296,
        fa_gittip = 0xf184,
        fa_glass = 0xf000,
        fa_glide = 0xf2a5,
        fa_glide_g = 0xf2a6,
        fa_globe = 0xf0ac,
        fa_google = 0xf1a0,
        fa_google_plus = 0xf0d5,
        fa_google_plus_circle = 0xf2b3,
        fa_google_plus_official = 0xf2b3,
        fa_google_plus_square = 0xf0d4,
        fa_google_wallet = 0xf1ee,
        fa_graduation_cap = 0xf19d,
        fa_gratipay = 0xf184,
        fa_grav = 0xf2d6,
        fa_group = 0xf0c0,
        fa_h_square = 0xf0fd,
        fa_hacker_news = 0xf1d4,
        fa_hand_grab_o = 0xf255,
        fa_hand_lizard_o = 0xf258,
        fa_hand_o_down = 0xf0a7,
        fa_hand_o_left = 0xf0a5,
        fa_hand_o_right = 0xf0a4,
        fa_hand_o_up = 0xf0a6,
        fa_hand_paper_o = 0xf256,
        fa_hand_peace_o = 0xf25b,
        fa_hand_pointer_o = 0xf25a,
        fa_hand_rock_o = 0xf255,
        fa_hand_scissors_o = 0xf257,
        fa_hand_spock_o = 0xf259,
        fa_hand_stop_o = 0xf256,
        fa_handshake_o = 0xf2b5,
        fa_hard_of_hearing = 0xf2a4,
        fa_hashtag = 0xf292,
        fa_hdd_o = 0xf0a0,
        fa_header = 0xf1dc,
        fa_headphones = 0xf025,
        fa_heart = 0xf004,
        fa_heart_o = 0xf08a,
        fa_heartbeat = 0xf21e,
        fa_history = 0xf1da,
        fa_home = 0xf015,
        fa_hospital_o = 0xf0f8,
        fa_hotel = 0xf236,
        fa_hourglass = 0xf254,
        fa_hourglass_1 = 0xf251,
        fa_hourglass_2 = 0xf252,
        fa_hourglass_3 = 0xf253,
        fa_hourglass_end = 0xf253,
        fa_hourglass_half = 0xf252,
        fa_hourglass_o = 0xf250,
        fa_hourglass_start = 0xf251,
        fa_houzz = 0xf27c,
        fa_html5 = 0xf13b,
        fa_i_cursor = 0xf246,
        fa_id_badge = 0xf2c1,
        fa_id_card = 0xf2c2,
        fa_id_card_o = 0xf2c3,
        fa_ils = 0xf20b,
        fa_image = 0xf03e,
        fa_imdb = 0xf2d8,
        fa_inbox = 0xf01c,
        fa_indent = 0xf03c,
        fa_industry = 0xf275,
        fa_info = 0xf129,
        fa_info_circle = 0xf05a,
        fa_inr = 0xf156,
        fa_instagram = 0xf16d,
        fa_institution = 0xf19c,
        fa_internet_explorer = 0xf26b,
        fa_intersex = 0xf224,
        fa_ioxhost = 0xf208,
        fa_italic = 0xf033,
        fa_joomla = 0xf1aa,
        fa_jpy = 0xf157,
        fa_jsfiddle = 0xf1cc,
        fa_key = 0xf084,
        fa_keyboard_o = 0xf11c,
        fa_krw = 0xf159,
        fa_language = 0xf1ab,
        fa_laptop = 0xf109,
        fa_lastfm = 0xf202,
        fa_lastfm_square = 0xf203,
        fa_leaf = 0xf06c,
        fa_leanpub = 0xf212,
        fa_legal = 0xf0e3,
        fa_lemon_o = 0xf094,
        fa_level_down = 0xf149,
        fa_level_up = 0xf148,
        fa_life_bouy = 0xf1cd,
        fa_life_buoy = 0xf1cd,
        fa_life_ring = 0xf1cd,
        fa_life_saver = 0xf1cd,
        fa_lightbulb_o = 0xf0eb,
        fa_line_chart = 0xf201,
        fa_link = 0xf0c1,
        fa_linkedin = 0xf0e1,
        fa_linkedin_square = 0xf08c,
        fa_linode = 0xf2b8,
        fa_linux = 0xf17c,
        fa_list = 0xf03a,
        fa_list_alt = 0xf022,
        fa_list_ol = 0xf0cb,
        fa_list_ul = 0xf0ca,
        fa_location_arrow = 0xf124,
        fa_lock = 0xf023,
        fa_long_arrow_down = 0xf175,
        fa_long_arrow_left = 0xf177,
        fa_long_arrow_right = 0xf178,
        fa_long_arrow_up = 0xf176,
        fa_low_vision = 0xf2a8,
        fa_magic = 0xf0d0,
        fa_magnet = 0xf076,
        fa_mail_forward = 0xf064,
        fa_mail_reply = 0xf112,
        fa_mail_reply_all = 0xf122,
        fa_male = 0xf183,
        fa_map = 0xf279,
        fa_map_marker = 0xf041,
        fa_map_o = 0xf278,
        fa_map_pin = 0xf276,
        fa_map_signs = 0xf277,
        fa_mars = 0xf222,
        fa_mars_double = 0xf227,
        fa_mars_stroke = 0xf229,
        fa_mars_stroke_h = 0xf22b,
        fa_mars_stroke_v = 0xf22a,
        fa_maxcdn = 0xf136,
        fa_meanpath = 0xf20c,
        fa_medium = 0xf23a,
        fa_medkit = 0xf0fa,
        fa_meetup = 0xf2e0,
        fa_meh_o = 0xf11a,
        fa_mercury = 0xf223,
        fa_microchip = 0xf2db,
        fa_microphone = 0xf130,
        fa_microphone_slash = 0xf131,
        fa_minus = 0xf068,
        fa_minus_circle = 0xf056,
        fa_minus_square = 0xf146,
        fa_minus_square_o = 0xf147,
        fa_mixcloud = 0xf289,
        fa_mobile = 0xf10b,
        fa_mobile_phone = 0xf10b,
        fa_modx = 0xf285,
        fa_money = 0xf0d6,
        fa_moon_o = 0xf186,
        fa_mortar_board = 0xf19d,
        fa_motorcycle = 0xf21c,
        fa_mouse_pointer = 0xf245,
        fa_music = 0xf001,
        fa_navicon = 0xf0c9,
        fa_neuter = 0xf22c,
        fa_newspaper_o = 0xf1ea,
        fa_object_group = 0xf247,
        fa_object_ungroup = 0xf248,
        fa_odnoklassniki = 0xf263,
        fa_odnoklassniki_square = 0xf264,
        fa_opencart = 0xf23d,
        fa_openid = 0xf19b,
        fa_opera = 0xf26a,
        fa_optin_monster = 0xf23c,
        fa_outdent = 0xf03b,
        fa_pagelines = 0xf18c,
        fa_paint_brush = 0xf1fc,
        fa_paper_plane = 0xf1d8,
        fa_paper_plane_o = 0xf1d9,
        fa_paperclip = 0xf0c6,
        fa_paragraph = 0xf1dd,
        fa_paste = 0xf0ea,
        fa_pause = 0xf04c,
        fa_pause_circle = 0xf28b,
        fa_pause_circle_o = 0xf28c,
        fa_paw = 0xf1b0,
        fa_paypal = 0xf1ed,
        fa_pencil = 0xf040,
        fa_pencil_square = 0xf14b,
        fa_pencil_square_o = 0xf044,
        fa_percent = 0xf295,
        fa_phone = 0xf095,
        fa_phone_square = 0xf098,
        fa_photo = 0xf03e,
        fa_picture_o = 0xf03e,
        fa_pie_chart = 0xf200,
        fa_pied_piper = 0xf2ae,
        fa_pied_piper_alt = 0xf1a8,
        fa_pied_piper_pp = 0xf1a7,
        fa_pinterest = 0xf0d2,
        fa_pinterest_p = 0xf231,
        fa_pinterest_square = 0xf0d3,
        fa_plane = 0xf072,
        fa_play = 0xf04b,
        fa_play_circle = 0xf144,
        fa_play_circle_o = 0xf01d,
        fa_plug = 0xf1e6,
        fa_plus = 0xf067,
        fa_plus_circle = 0xf055,
        fa_plus_square = 0xf0fe,
        fa_plus_square_o = 0xf196,
        fa_podcast = 0xf2ce,
        fa_power_off = 0xf011,
        fa_print = 0xf02f,
        fa_product_hunt = 0xf288,
        fa_puzzle_piece = 0xf12e,
        fa_qq = 0xf1d6,
        fa_qrcode = 0xf029,
        fa_question = 0xf128,
        fa_question_circle = 0xf059,
        fa_question_circle_o = 0xf29c,
        fa_quora = 0xf2c4,
        fa_quote_left = 0xf10d,
        fa_quote_right = 0xf10e,
        fa_ra = 0xf1d0,
        fa_random = 0xf074,
        fa_ravelry = 0xf2d9,
        fa_rebel = 0xf1d0,
        fa_recycle = 0xf1b8,
        fa_reddit = 0xf1a1,
        fa_reddit_alien = 0xf281,
        fa_reddit_square = 0xf1a2,
        fa_refresh = 0xf021,
        fa_registered = 0xf25d,
        fa_remove = 0xf00d,
        fa_renren = 0xf18b,
        fa_reorder = 0xf0c9,
        fa_repeat = 0xf01e,
        fa_reply = 0xf112,
        fa_reply_all = 0xf122,
        fa_resistance = 0xf1d0,
        fa_retweet = 0xf079,
        fa_rmb = 0xf157,
        fa_road = 0xf018,
        fa_rocket = 0xf135,
        fa_rotate_left = 0xf0e2,
        fa_rotate_right = 0xf01e,
        fa_rouble = 0xf158,
        fa_rss = 0xf09e,
        fa_rss_square = 0xf143,
        fa_rub = 0xf158,
        fa_ruble = 0xf158,
        fa_rupee = 0xf156,
        fa_s15 = 0xf2cd,
        fa_safari = 0xf267,
        fa_save = 0xf0c7,
        fa_scissors = 0xf0c4,
        fa_scribd = 0xf28a,
        fa_search = 0xf002,
        fa_search_minus = 0xf010,
        fa_search_plus = 0xf00e,
        fa_sellsy = 0xf213,
        fa_send = 0xf1d8,
        fa_send_o = 0xf1d9,
        fa_server = 0xf233,
        fa_share = 0xf064,
        fa_share_alt = 0xf1e0,
        fa_share_alt_square = 0xf1e1,
        fa_share_square = 0xf14d,
        fa_share_square_o = 0xf045,
        fa_shekel = 0xf20b,
        fa_sheqel = 0xf20b,
        fa_shield = 0xf132,
        fa_ship = 0xf21a,
        fa_shirtsinbulk = 0xf214,
        fa_shopping_bag = 0xf290,
        fa_shopping_basket = 0xf291,
        fa_shopping_cart = 0xf07a,
        fa_shower = 0xf2cc,
        fa_sign_in = 0xf090,
        fa_sign_language = 0xf2a7,
        fa_sign_out = 0xf08b,
        fa_signal = 0xf012,
        fa_signing = 0xf2a7,
        fa_simplybuilt = 0xf215,
        fa_sitemap = 0xf0e8,
        fa_skyatlas = 0xf216,
        fa_skype = 0xf17e,
        fa_slack = 0xf198,
        fa_sliders = 0xf1de,
        fa_slideshare = 0xf1e7,
        fa_smile_o = 0xf118,
        fa_snapchat = 0xf2ab,
        fa_snapchat_ghost = 0xf2ac,
        fa_snapchat_square = 0xf2ad,
        fa_snowflake_o = 0xf2dc,
        fa_soccer_ball_o = 0xf1e3,
        fa_sort = 0xf0dc,
        fa_sort_alpha_asc = 0xf15d,
        fa_sort_alpha_desc = 0xf15e,
        fa_sort_amount_asc = 0xf160,
        fa_sort_amount_desc = 0xf161,
        fa_sort_asc = 0xf0de,
        fa_sort_desc = 0xf0dd,
        fa_sort_down = 0xf0dd,
        fa_sort_numeric_asc = 0xf162,
        fa_sort_numeric_desc = 0xf163,
        fa_sort_up = 0xf0de,
        fa_soundcloud = 0xf1be,
        fa_space_shuttle = 0xf197,
        fa_spinner = 0xf110,
        fa_spoon = 0xf1b1,
        fa_spotify = 0xf1bc,
        fa_square = 0xf0c8,
        fa_square_o = 0xf096,
        fa_stack_exchange = 0xf18d,
        fa_stack_overflow = 0xf16c,
        fa_star = 0xf005,
        fa_star_half = 0xf089,
        fa_star_half_empty = 0xf123,
        fa_star_half_full = 0xf123,
        fa_star_half_o = 0xf123,
        fa_star_o = 0xf006,
        fa_steam = 0xf1b6,
        fa_steam_square = 0xf1b7,
        fa_step_backward = 0xf048,
        fa_step_forward = 0xf051,
        fa_stethoscope = 0xf0f1,
        fa_sticky_note = 0xf249,
        fa_sticky_note_o = 0xf24a,
        fa_stop = 0xf04d,
        fa_stop_circle = 0xf28d,
        fa_stop_circle_o = 0xf28e,
        fa_street_view = 0xf21d,
        fa_strikethrough = 0xf0cc,
        fa_stumbleupon = 0xf1a4,
        fa_stumbleupon_circle = 0xf1a3,
        fa_subscript = 0xf12c,
        fa_subway = 0xf239,
        fa_suitcase = 0xf0f2,
        fa_sun_o = 0xf185,
        fa_superpowers = 0xf2dd,
        fa_superscript = 0xf12b,
        fa_support = 0xf1cd,
        fa_table = 0xf0ce,
        fa_tablet = 0xf10a,
        fa_tachometer = 0xf0e4,
        fa_tag = 0xf02b,
        fa_tags = 0xf02c,
        fa_tasks = 0xf0ae,
        fa_taxi = 0xf1ba,
        fa_telegram = 0xf2c6,
        fa_television = 0xf26c,
        fa_tencent_weibo = 0xf1d5,
        fa_terminal = 0xf120,
        fa_text_height = 0xf034,
        fa_text_width = 0xf035,
        fa_th = 0xf00a,
        fa_th_large = 0xf009,
        fa_th_list = 0xf00b,
        fa_themeisle = 0xf2b2,
        fa_thermometer = 0xf2c7,
        fa_thermometer_0 = 0xf2cb,
        fa_thermometer_1 = 0xf2ca,
        fa_thermometer_2 = 0xf2c9,
        fa_thermometer_3 = 0xf2c8,
        fa_thermometer_4 = 0xf2c7,
        fa_thermometer_empty = 0xf2cb,
        fa_thermometer_full = 0xf2c7,
        fa_thermometer_half = 0xf2c9,
        fa_thermometer_quarter = 0xf2ca,
        fa_thermometer_three_quarters = 0xf2c8,
        fa_thumb_tack = 0xf08d,
        fa_thumbs_down = 0xf165,
        fa_thumbs_o_down = 0xf088,
        fa_thumbs_o_up = 0xf087,
        fa_thumbs_up = 0xf164,
        fa_ticket = 0xf145,
        fa_times = 0xf00d,
        fa_times_circle = 0xf057,
        fa_times_circle_o = 0xf05c,
        fa_times_rectangle = 0xf2d3,
        fa_times_rectangle_o = 0xf2d4,
        fa_tint = 0xf043,
        fa_toggle_down = 0xf150,
        fa_toggle_left = 0xf191,
        fa_toggle_off = 0xf204,
        fa_toggle_on = 0xf205,
        fa_toggle_right = 0xf152,
        fa_toggle_up = 0xf151,
        fa_trademark = 0xf25c,
        fa_train = 0xf238,
        fa_transgender = 0xf224,
        fa_transgender_alt = 0xf225,
        fa_trash = 0xf1f8,
        fa_trash_o = 0xf014,
        fa_tree = 0xf1bb,
        fa_trello = 0xf181,
        fa_tripadvisor = 0xf262,
        fa_trophy = 0xf091,
        fa_truck = 0xf0d1,
        fa_try = 0xf195,
        fa_tty = 0xf1e4,
        fa_tumblr = 0xf173,
        fa_tumblr_square = 0xf174,
        fa_turkish_lira = 0xf195,
        fa_tv = 0xf26c,
        fa_twitch = 0xf1e8,
        fa_twitter = 0xf099,
        fa_twitter_square = 0xf081,
        fa_umbrella = 0xf0e9,
        fa_underline = 0xf0cd,
        fa_undo = 0xf0e2,
        fa_universal_access = 0xf29a,
        fa_university = 0xf19c,
        fa_unlink = 0xf127,
        fa_unlock = 0xf09c,
        fa_unlock_alt = 0xf13e,
        fa_unsorted = 0xf0dc,
        fa_upload = 0xf093,
        fa_usb = 0xf287,
        fa_usd = 0xf155,
        fa_user = 0xf007,
        fa_user_circle = 0xf2bd,
        fa_user_circle_o = 0xf2be,
        fa_user_md = 0xf0f0,
        fa_user_o = 0xf2c0,
        fa_user_plus = 0xf234,
        fa_user_secret = 0xf21b,
        fa_user_times = 0xf235,
        fa_users = 0xf0c0,
        fa_vcard = 0xf2bb,
        fa_vcard_o = 0xf2bc,
        fa_venus = 0xf221,
        fa_venus_double = 0xf226,
        fa_venus_mars = 0xf228,
        fa_viacoin = 0xf237,
        fa_viadeo = 0xf2a9,
        fa_viadeo_square = 0xf2aa,
        fa_video_camera = 0xf03d,
        fa_vimeo = 0xf27d,
        fa_vimeo_square = 0xf194,
        fa_vine = 0xf1ca,
        fa_vk = 0xf189,
        fa_volume_control_phone = 0xf2a0,
        fa_volume_down = 0xf027,
        fa_volume_off = 0xf026,
        fa_volume_up = 0xf028,
        fa_warning = 0xf071,
        fa_wechat = 0xf1d7,
        fa_weibo = 0xf18a,
        fa_weixin = 0xf1d7,
        fa_whatsapp = 0xf232,
        fa_wheelchair = 0xf193,
        fa_wheelchair_alt = 0xf29b,
        fa_wifi = 0xf1eb,
        fa_wikipedia_w = 0xf266,
        fa_window_close = 0xf2d3,
        fa_window_close_o = 0xf2d4,
        fa_window_maximize = 0xf2d0,
        fa_window_minimize = 0xf2d1,
        fa_window_restore = 0xf2d2,
        fa_windows = 0xf17a,
        fa_won = 0xf159,
        fa_wordpress = 0xf19a,
        fa_wpbeginner = 0xf297,
        fa_wpexplorer = 0xf2de,
        fa_wpforms = 0xf298,
        fa_wrench = 0xf0ad,
        fa_xing = 0xf168,
        fa_xing_square = 0xf169,
        fa_y_combinator = 0xf23b,
        fa_y_combinator_square = 0xf1d4,
        fa_yahoo = 0xf19e,
        fa_yc = 0xf23b,
        fa_yc_square = 0xf1d4,
        fa_yelp = 0xf1e9,
        fa_yen = 0xf157,
        fa_yoast = 0xf2b1,
        fa_youtube = 0xf167,
        fa_youtube_play = 0xf16a,
        fa_youtube_square = 0xf166,

        // ruleset icons in circles
        fa_osu_osu_o = 0xe000,
        fa_osu_mania_o = 0xe001,
        fa_osu_fruits_o = 0xe002,
        fa_osu_taiko_o = 0xe003,

        // ruleset icons without circles
        fa_osu_filled_circle = 0xe004,
        fa_osu_cross_o = 0xe005,
        fa_osu_logo = 0xe006,
        fa_osu_chevron_down_o = 0xe007,
        fa_osu_edit_o = 0xe033,
        fa_osu_left_o = 0xe034,
        fa_osu_right_o = 0xe035,
        fa_osu_charts = 0xe036,
        fa_osu_solo = 0xe037,
        fa_osu_multi = 0xe038,
        fa_osu_gear = 0xe039,

        // misc icons
        fa_osu_bat = 0xe008,
        fa_osu_bubble = 0xe009,
        fa_osu_bubble_pop = 0xe02e,
        fa_osu_dice = 0xe011,
        fa_osu_heart1 = 0xe02f,
        fa_osu_heart1_break = 0xe030,
        fa_osu_hot = 0xe031,
        fa_osu_list_search = 0xe032,

        //osu! playstyles
        fa_osu_playstyle_tablet = 0xe02a,
        fa_osu_playstyle_mouse = 0xe029,
        fa_osu_playstyle_keyboard = 0xe02b,
        fa_osu_playstyle_touch = 0xe02c,

        // osu! difficulties
        fa_osu_easy_osu = 0xe015,
        fa_osu_normal_osu = 0xe016,
        fa_osu_hard_osu = 0xe017,
        fa_osu_insane_osu = 0xe018,
        fa_osu_expert_osu = 0xe019,

        // taiko difficulties
        fa_osu_easy_taiko = 0xe01a,
        fa_osu_normal_taiko = 0xe01b,
        fa_osu_hard_taiko = 0xe01c,
        fa_osu_insane_taiko = 0xe01d,
        fa_osu_expert_taiko = 0xe01e,

        // fruits difficulties
        fa_osu_easy_fruits = 0xe01f,
        fa_osu_normal_fruits = 0xe020,
        fa_osu_hard_fruits = 0xe021,
        fa_osu_insane_fruits = 0xe022,
        fa_osu_expert_fruits = 0xe023,

        // mania difficulties
        fa_osu_easy_mania = 0xe024,
        fa_osu_normal_mania = 0xe025,
        fa_osu_hard_mania = 0xe026,
        fa_osu_insane_mania = 0xe027,
        fa_osu_expert_mania = 0xe028,

        // mod icons
        fa_osu_mod_perfect = 0xe02d,
        fa_osu_mod_autopilot = 0xe03a,
        fa_osu_mod_auto = 0xe03b,
        fa_osu_mod_cinema = 0xe03c,
        fa_osu_mod_doubletime = 0xe03d,
        fa_osu_mod_easy = 0xe03e,
        fa_osu_mod_flashlight = 0xe03f,
        fa_osu_mod_halftime = 0xe040,
        fa_osu_mod_hardrock = 0xe041,
        fa_osu_mod_hidden = 0xe042,
        fa_osu_mod_nightcore = 0xe043,
        fa_osu_mod_nofail = 0xe044,
        fa_osu_mod_relax = 0xe045,
        fa_osu_mod_spunout = 0xe046,
        fa_osu_mod_suddendeath = 0xe047,
        fa_osu_mod_target = 0xe048,
        fa_osu_mod_bg = 0xe04a,
    }
}
