<?php

class FurAffinityBridge extends BridgeAbstract
{
    const NAME = 'FurAffinity Bridge';
    const URI = 'https://www.furaffinity.net';
    const CACHE_TIMEOUT = 300; // 5min
    const DESCRIPTION = 'Returns posts from various sections of FurAffinity';
    const MAINTAINER = 'Roliga, mruac';
    const CONFIGURATION = [
        'aCookie' => [
            'required' => false,
            'defaultValue' => 'ca6e4566-9d81-4263-9444-653b142e35f8'

        ],
        'bCookie' => [
            'required' => false,
            'defaultValue' => '4ce65691-b50f-4742-a990-bf28d6de16ee'
        ]
    ];
    const PARAMETERS = [
        'Search' => [
            'q' => [
                'name' => 'Query',
                'required' => true,
                'exampleValue' => 'dog',
            ],
            'rating-general' => [
                'name' => 'General',
                'type' => 'checkbox',
                'defaultValue' => 'checked'
            ],
            'rating-mature' => [
                'name' => 'Mature',
                'type' => 'checkbox',
            ],
            'rating-adult' => [
                'name' => 'Adult',
                'type' => 'checkbox',
            ],
            'range' => [
                'name' => 'Time range',
                'type' => 'list',
                'values' => [
                    'A Day' => 'day',
                    '3 Days' => '3days',
                    'A Week' => 'week',
                    'A Month' => 'month',
                    'All time' => 'all'
                ],
                'defaultValue' => 'all'
            ],
            'type-art' => [
                'name' => 'Art',
                'type' => 'checkbox',
                'defaultValue' => 'checked'
            ],
            'type-flash' => [
                'name' => 'Flash',
                'type' => 'checkbox',
                'defaultValue' => 'checked'
            ],
            'type-photo' => [
                'name' => 'Photography',
                'type' => 'checkbox',
                'defaultValue' => 'checked'
            ],
            'type-music' => [
                'name' => 'Music',
                'type' => 'checkbox',
                'defaultValue' => 'checked'
            ],
            'type-story' => [
                'name' => 'Story',
                'type' => 'checkbox',
                'defaultValue' => 'checked'
            ],
            'type-poetry' => [
                'name' => 'Poetry',
                'type' => 'checkbox',
                'defaultValue' => 'checked'
            ],
            'mode' => [
                'name' => 'Match mode',
                'type' => 'list',
                'values' => [
                    'All of the words' => 'all',
                    'Any of the words' => 'any',
                    'Extended' => 'extended'
                ],
                'defaultValue' => 'extended'
            ],
            'limit' => [
                'name' => 'Limit',
                'type' => 'number',
                'required' => true,
                'defaultValue' => 10,
                'title' => 'Limit number of submissions to return. -1 for unlimited.'
            ],
            'full' => [
                'name' => 'Full view',
                'title' => 'Include description, tags, date and larger image in article. Uses more bandwidth.',
                'type' => 'checkbox',
                'defaultValue' => 'checked'
            ],
            'cache' => [
                'name' => 'Cache submission pages',
                'title' => 'Reduces requests to FA when Full view is enabled. Changes to submission details may be delayed.',
                'type' => 'checkbox',
                'defaultValue' => 'checked'
            ]
        ],
        'Browse' => [
            'cat' => [
                'name' => 'Category',
                'type' => 'list',
                'values' => [
                    'Visual Art' => [
                        'All' => 1,
                        'Artwork (Digital)' => 2,
                        'Artwork (Traditional)' => 3,
                        'Cellshading' => 4,
                        'Crafting' => 5,
                        'Designs' => 6,
                        'Flash' => 7,
                        'Fursuiting' => 8,
                        'Icons' => 9,
                        'Mosaics' => 10,
                        'Photography' => 11,
                        'Sculpting' => 12
                    ],
                    'Readable Art' => [
                        'Story' => 13,
                        'Poetry' => 14,
                        'Prose' => 15
                    ],
                    'Audio Art' => [
                        'Music' => 16,
                        'Podcasts' => 17
                    ],
                    'Downloadable' => [
                        'Skins' => 18,
                        'Handhelds' => 19,
                        'Resources' => 20
                    ],
                    'Other Stuff' => [
                        'Adoptables' => 21,
                        'Auctions' => 22,
                        'Contests' => 23,
                        'Current Events' => 24,
                        'Desktops' => 25,
                        'Stockart' => 26,
                        'Screenshots' => 27,
                        'Scraps' => 28,
                        'Wallpaper' => 29,
                        'YCH / Sale' => 30,
                        'Other' => 31
                    ]
                ],
                'defaultValue' => 1
            ],
            'atype' => [
                'name' => 'Type',
                'type' => 'list',
                'values' => [
                    'General Things' => [
                        'All' => 1,
                        'Abstract' => 2,
                        'Animal related (non-anthro)' => 3,
                        'Anime' => 4,
                        'Comics' => 5,
                        'Doodle' => 6,
                        'Fanart' => 7,
                        'Fantasy' => 8,
                        'Human' => 9,
                        'Portraits' => 10,
                        'Scenery' => 11,
                        'Still Life' => 12,
                        'Tutorials' => 13,
                        'Miscellaneous' => 14
                    ],
                    'Fetish / Furry specialty' => [
                        'Baby fur' => 101,
                        'Bondage' => 102,
                        'Digimon' => 103,
                        'Fat Furs' => 104,
                        'Fetish Other' => 105,
                        'Fursuit' => 106,
                        'Gore / Macabre Art' => 119,
                        'Hyper' => 107,
                        'Inflation' => 108,
                        'Macro / Micro' => 109,
                        'Muscle' => 110,
                        'My Little Pony / Brony' => 111,
                        'Paw' => 112,
                        'Pokemon' => 113,
                        'Pregnancy' => 114,
                        'Sonic' => 115,
                        'Transformation' => 116,
                        'Vore' => 117,
                        'Water Sports' => 118,
                        'General Furry Art' => 100
                    ],
                    'Music' => [
                        'Techno' => 201,
                        'Trance' => 202,
                        'House' => 203,
                        '90s' => 204,
                        '80s' => 205,
                        '70s' => 206,
                        '60s' => 207,
                        'Pre-60s' => 208,
                        'Classical' => 209,
                        'Game Music' => 210,
                        'Rock' => 211,
                        'Pop' => 212,
                        'Rap' => 213,
                        'Industrial' => 214,
                        'Other Music' => 200
                    ]
                ],
                'defaultValue' => 1
            ],
            'species' => [
                'name' => 'Species',
                'type' => 'list',
                'values' => [
                    'Unspecified / Any' => 1,
                    'Amphibian' => [
                        'Frog' => 1001,
                        'Newt' => 1002,
                        'Salamander' => 1003,
                        'Amphibian (Other)' => 1000
                    ],
                    'Aquatic' => [
                        'Cephalopod' => 2001,
                        'Dolphin' => 2002,
                        'Fish' => 2005,
                        'Porpoise' => 2004,
                        'Seal' => 6068,
                        'Shark' => 2006,
                        'Whale' => 2003,
                        'Aquatic (Other)' => 2000
                    ],
                    'Avian' => [
                        'Corvid' => 3001,
                        'Crow' => 3002,
                        'Duck' => 3003,
                        'Eagle' => 3004,
                        'Falcon' => 3005,
                        'Goose' => 3006,
                        'Gryphon' => 3007,
                        'Hawk' => 3008,
                        'Owl' => 3009,
                        'Phoenix' => 3010,
                        'Swan' => 3011,
                        'Avian (Other)' => 3000
                    ],
                    'Bears &amp; Ursines' => [
                        'Bear' => 6002
                    ],
                    'Camelids' => [
                        'Camel' => 6074,
                        'Llama' => 6036
                    ],
                    'Canines &amp; Lupines' => [
                        'Coyote' => 6008,
                        'Doberman' => 6009,
                        'Dog' => 6010,
                        'Dingo' => 6011,
                        'German Shepherd' => 6012,
                        'Jackal' => 6013,
                        'Husky' => 6014,
                        'Wolf' => 6016,
                        'Canine (Other)' => 6017
                    ],
                    'Cervines' => [
                        'Cervine (Other)' => 6018
                    ],
                    'Cows &amp; Bovines' => [
                        'Antelope' => 6004,
                        'Cows' => 6003,
                        'Gazelle' => 6005,
                        'Goat' => 6006,
                        'Bovines (General)' => 6007
                    ],
                    'Dragons' => [
                        'Eastern Dragon' => 4001,
                        'Hydra' => 4002,
                        'Serpent' => 4003,
                        'Western Dragon' => 4004,
                        'Wyvern' => 4005,
                        'Dragon (Other)' => 4000
                    ],
                    'Equestrians' => [
                        'Donkey' => 6019,
                        'Horse' => 6034,
                        'Pony' => 6073,
                        'Zebra' => 6071
                    ],
                    'Exotic &amp; Mythicals' => [
                        'Argonian' => 5002,
                        'Chakat' => 5003,
                        'Chocobo' => 5004,
                        'Citra' => 5005,
                        'Crux' => 5006,
                        'Daemon' => 5007,
                        'Digimon' => 5008,
                        'Dracat' => 5009,
                        'Draenei' => 5010,
                        'Elf' => 5011,
                        'Gargoyle' => 5012,
                        'Iksar' => 5013,
                        'Kaiju/Monster' => 5015,
                        'Langurhali' => 5014,
                        'Moogle' => 5017,
                        'Naga' => 5016,
                        'Orc' => 5018,
                        'Pokemon' => 5019,
                        'Satyr' => 5020,
                        'Sergal' => 5021,
                        'Tanuki' => 5022,
                        'Unicorn' => 5023,
                        'Xenomorph' => 5024,
                        'Alien (Other)' => 5001,
                        'Exotic (Other)' => 5000
                    ],
                    'Felines' => [
                        'Domestic Cat' => 6020,
                        'Cheetah' => 6021,
                        'Cougar' => 6022,
                        'Jaguar' => 6023,
                        'Leopard' => 6024,
                        'Lion' => 6025,
                        'Lynx' => 6026,
                        'Ocelot' => 6027,
                        'Panther' => 6028,
                        'Tiger' => 6029,
                        'Feline (Other)' => 6030
                    ],
                    'Insects' => [
                        'Arachnid' => 8000,
                        'Mantid' => 8004,
                        'Scorpion' => 8005,
                        'Insect (Other)' => 8003
                    ],
                    'Mammals (Other)' => [
                        'Bat' => 6001,
                        'Giraffe' => 6031,
                        'Hedgehog' => 6032,
                        'Hippopotamus' => 6033,
                        'Hyena' => 6035,
                        'Panda' => 6052,
                        'Pig/Swine' => 6053,
                        'Rabbit/Hare' => 6059,
                        'Raccoon' => 6060,
                        'Red Panda' => 6062,
                        'Meerkat' => 6043,
                        'Mongoose' => 6044,
                        'Rhinoceros' => 6063,
                        'Mammals (Other)' => 6000
                    ],
                    'Marsupials' => [
                        'Opossum' => 6037,
                        'Kangaroo' => 6038,
                        'Koala' => 6039,
                        'Quoll' => 6040,
                        'Wallaby' => 6041,
                        'Marsupial (Other)' => 6042
                    ],
                    'Mustelids' => [
                        'Badger' => 6045,
                        'Ferret' => 6046,
                        'Mink' => 6048,
                        'Otter' => 6047,
                        'Skunk' => 6069,
                        'Weasel' => 6049,
                        'Mustelid (Other)' => 6051
                    ],
                    'Primates' => [
                        'Gorilla' => 6054,
                        'Human' => 6055,
                        'Lemur' => 6056,
                        'Monkey' => 6057,
                        'Primate (Other)' => 6058
                    ],
                    'Reptillian' => [
                        'Alligator &amp; Crocodile' => 7001,
                        'Gecko' => 7003,
                        'Iguana' => 7004,
                        'Lizard' => 7005,
                        'Snakes &amp; Serpents' => 7006,
                        'Turtle' => 7007,
                        'Reptilian (Other)' => 7000
                    ],
                    'Rodents' => [
                        'Beaver' => 6064,
                        'Mouse' => 6065,
                        'Rat' => 6061,
                        'Squirrel' => 6070,
                        'Rodent (Other)' => 6067
                    ],
                    'Vulpines' => [
                        'Fennec' => 6072,
                        'Fox' => 6075,
                        'Vulpine (Other)' => 6015
                    ],
                    'Other' => [
                        'Dinosaur' => 8001,
                        'Wolverine' => 6050
                    ]
                ],
                'defaultValue' => 1
            ],
            'gender' => [
                'name' => 'Gender',
                'type' => 'list',
                'values' => [
                    'Any' => 0,
                    'Male' => 2,
                    'Female' => 3,
                    'Herm' => 4,
                    'Transgender' => 5,
                    'Multiple characters' => 6,
                    'Other / Not Specified' => 7
                ],
                'defaultValue' => 0
            ],
            'rating_general' => [
                'name' => 'General',
                'type' => 'checkbox',
                'defaultValue' => 'checked'
            ],
            'rating_mature' => [
                'name' => 'Mature',
                'type' => 'checkbox',
            ],
            'rating_adult' => [
                'name' => 'Adult',
                'type' => 'checkbox',
            ],
            'limit-browse' => [
                'name' => 'Limit',
                'type' => 'number',
                'required' => true,
                'defaultValue' => 10,
                'title' => 'Limit number of submissions to return. -1 for unlimited.'
            ],
            'full' => [
                'name' => 'Full view',
                'title' => 'Include description, tags, date and larger image in article. Uses more bandwidth.',
                'type' => 'checkbox',
                'defaultValue' => 'checked'
            ],
            'cache' => [
                'name' => 'Cache submission pages',
                'title' => 'Reduces requests to FA when Full view is enabled. Changes to submission details may be delayed.',
                'type' => 'checkbox',
                'defaultValue' => 'checked'
            ]

        ],
        'Journals' => [
            'username-journals' => [
                'name' => 'Username',
                'required' => true,
                'exampleValue' => 'dhw',
                'title' => 'Lowercase username as seen in URLs'
            ],
            'limit' => [
                'name' => 'Limit',
                'type' => 'number',
                'defaultValue' => -1,
                'title' => 'Limit number of journals to return. -1 for unlimited.'
            ]

        ],
        'Single Journal' => [
            'journal-id' => [
                'name' => 'Journal ID',
                'required' => true,
                'exampleValue' => '10008853',
                'type' => 'number',
                'title' => 'Number seen in journal URL'
            ]
        ],
        'Gallery' => [
            'username-gallery' => [
                'name' => 'Username',
                'required' => true,
                'exampleValue' => 'dhw',
                'title' => 'Lowercase username as seen in URLs'
            ],
            'limit' => [
                'name' => 'Limit',
                'type' => 'number',
                'required' => true,
                'defaultValue' => 10,
                'title' => 'Limit number of submissions to return. -1 for unlimited.'
            ],
            'full' => [
                'name' => 'Full view',
                'title' => 'Include description, tags, date and larger image in article. Uses more bandwidth.',
                'type' => 'checkbox',
                'defaultValue' => 'checked'
            ],
            'cache' => [
                'name' => 'Cache submission pages',
                'title' => 'Reduces requests to FA when Full view is enabled. Changes to submission details may be delayed.',
                'type' => 'checkbox',
                'defaultValue' => 'checked'
            ]
        ],
        'Scraps' => [
            'username-scraps' => [
                'name' => 'Username',
                'required' => true,
                'exampleValue' => 'dhw',
                'title' => 'Lowercase username as seen in URLs'
            ],
            'limit' => [
                'name' => 'Limit',
                'type' => 'number',
                'required' => true,
                'defaultValue' => 10,
                'title' => 'Limit number of submissions to return. -1 for unlimited.'
            ],
            'full' => [
                'name' => 'Full view',
                'title' => 'Include description, tags, date and larger image in article. Uses more bandwidth.',
                'type' => 'checkbox',
                'defaultValue' => 'checked'
            ],
            'cache' => [
                'name' => 'Cache submission pages',
                'title' => 'Reduces requests to FA when Full view is enabled. Changes to submission details may be delayed.',
                'type' => 'checkbox',
                'defaultValue' => 'checked'
            ]
        ],
        'Favorites' => [
            'username-favorites' => [
                'name' => 'Username',
                'required' => true,
                'exampleValue' => 'dhw',
                'title' => 'Lowercase username as seen in URLs'
            ],
            'limit' => [
                'name' => 'Limit',
                'type' => 'number',
                'required' => true,
                'defaultValue' => 10,
                'title' => 'Limit number of submissions to return. -1 for unlimited.'
            ],
            'full' => [
                'name' => 'Full view',
                'title' => 'Include description, tags, date and larger image in article. Uses more bandwidth.',
                'type' => 'checkbox',
                'defaultValue' => 'checked'
            ],
            'cache' => [
                'name' => 'Cache submission pages',
                'title' => 'Reduces requests to FA when Full view is enabled. Changes to submission details may be delayed.',
                'type' => 'checkbox',
                'defaultValue' => 'checked'
            ]
        ],
        'Gallery Folder' => [
            'username-folder' => [
                'name' => 'Username',
                'required' => true,
                'exampleValue' => 'kopk',
                'title' => 'Lowercase username as seen in URLs'
            ],
            'folder-id' => [
                'name' => 'Folder ID',
                'required' => true,
                'exampleValue' => '1031990',
                'type' => 'number',
                'title' => 'Number seen in folder URL'
            ],
            'limit' => [
                'name' => 'Limit',
                'type' => 'number',
                'required' => true,
                'defaultValue' => 10,
                'title' => 'Limit number of submissions to return. -1 for unlimited.'
            ],
            'full' => [
                'name' => 'Full view',
                'title' => 'Include description, tags, date and larger image in article. Uses more bandwidth.',
                'type' => 'checkbox',
                'defaultValue' => 'checked'
            ],
            'cache' => [
                'name' => 'Cache submission pages',
                'title' => 'Reduces requests to FA when Full view is enabled. Changes to submission details may be delayed.',
                'type' => 'checkbox',
                'defaultValue' => 'checked'
            ]
        ]
    ];

    /*
     * This was aquired by creating a new user on FA then
     * extracting the cookie from the browsers dev console.
     */
    private $FA_AUTH_COOKIE;

    public function detectParameters($url)
    {
        $params = [];

        // Single journal
        $regex = '/^(https?:\/\/)?(www\.)?furaffinity.net\/journal\/(\d+)/';
        if (preg_match($regex, $url, $matches) > 0) {
            $params['context'] = 'Single Journal';
            $params['journal-id'] = urldecode($matches[3]);
            return $params;
        }

        // Journals
        $regex = '/^(https?:\/\/)?(www\.)?furaffinity.net\/journals\/([^\/&?\n]+)/';
        if (preg_match($regex, $url, $matches) > 0) {
            $params['context'] = 'Journals';
            $params['username-journals'] = urldecode($matches[3]);
            return $params;
        }

        // Gallery folder
        $regex = '/^(https?:\/\/)?(www\.)?furaffinity.net\/gallery\/([^\/&?\n]+)\/folder\/(\d+)/';
        if (preg_match($regex, $url, $matches) > 0) {
            $params['context'] = 'Gallery Folder';
            $params['username-folder'] = urldecode($matches[3]);
            $params['folder-id'] = urldecode($matches[4]);
            $params['full'] = 'on';
            return $params;
        }

        // Gallery (must be after gallery folder)
        $regex = '/^(https?:\/\/)?(www\.)?furaffinity.net\/(gallery|scraps|favorites)\/([^\/&?\n]+)/';
        if (preg_match($regex, $url, $matches) > 0) {
            $params['context'] = 'Gallery';
            $params['username-' . $matches[3]] = urldecode($matches[4]);
            $params['full'] = 'on';
            return $params;
        }

        return null;
    }

    public function getName()
    {
        switch ($this->queriedContext) {
            case 'Search':
                return 'Search For '
                . $this->getInput('q');
            case 'Browse':
                return 'Browse';
            case 'Journals':
                return $this->getInput('username-journals');
            case 'Single Journal':
                return 'Journal '
                . $this->getInput('journal-id');
            case 'Gallery':
                return $this->getInput('username-gallery');
            case 'Scraps':
                return $this->getInput('username-scraps');
            case 'Favorites':
                return $this->getInput('username-favorites');
            case 'Gallery Folder':
                return $this->getInput('username-folder')
                . '\'s Folder '
                . $this->getInput('folder-id');
            default:
                $name = parent::getName();
                if ($this->getOption('aCookie') !== null) {
                    $username = $this->loadCacheValue('username');
                    if ($username !== null) {
                        $name = $username . '\'s ' . parent::getName();
                    }
                }
                return $name;
        }
    }

    public function getDescription()
    {
        switch ($this->queriedContext) {
            case 'Search':
                return 'FurAffinity Search For '
                . $this->getInput('q');
            case 'Browse':
                return 'FurAffinity Browse';
            case 'Journals':
                return 'FurAffinity Journals By '
                . $this->getInput('username-journals');
            case 'Single Journal':
                return 'FurAffinity Journal '
                . $this->getInput('journal-id');
            case 'Gallery':
                return 'FurAffinity Gallery By '
                . $this->getInput('username-gallery');
            case 'Scraps':
                return 'FurAffinity Scraps By '
                . $this->getInput('username-scraps');
            case 'Favorites':
                return 'FurAffinity Favorites By '
                . $this->getInput('username-favorites');
            case 'Gallery Folder':
                return 'FurAffinity Gallery Folder '
                . $this->getInput('folder-id')
                . ' By '
                . $this->getInput('username-folder');
            default:
                return parent::getDescription();
        }
    }

    public function getURI()
    {
        switch ($this->queriedContext) {
            case 'Search':
                return self::URI
                . '/search';
            case 'Browse':
                return self::URI
                . '/browse';
            case 'Journals':
                return self::URI
                . '/journals/'
                . $this->getInput('username-journals');
            case 'Single Journal':
                return self::URI
                . '/journal/'
                . $this->getInput('journal-id');
            case 'Gallery':
                return self::URI
                . '/gallery/'
                . $this->getInput('username-gallery');
            case 'Scraps':
                return self::URI
                . '/scraps/'
                . $this->getInput('username-scraps');
            case 'Favorites':
                return self::URI
                . '/favorites/'
                . $this->getInput('username-favorites');
            case 'Gallery Folder':
                return self::URI
                . '/gallery/'
                . $this->getInput('username-folder')
                . '/folder/'
                . $this->getInput('folder-id');
            default:
                return parent::getURI();
        }
    }

    public function collectData()
    {
        $this->FA_AUTH_COOKIE = 'b=' . $this->getOption('bCookie') . '; a=' . $this->getOption('aCookie');
        switch ($this->queriedContext) {
            case 'Search':
                $data = [
                'q' => $this->getInput('q'),
                'perpage' => 72,
                'rating-general' => ($this->getInput('rating-general') === true ? 'on' : 0),
                'rating-mature' => ($this->getInput('rating-mature') === true ? 'on' : 0),
                'rating-adult' => ($this->getInput('rating-adult') === true ? 'on' : 0),
                'range' => $this->getInput('range'),
                'type-art' => ($this->getInput('type-art') === true ? 'on' : 0),
                'type-flash' => ($this->getInput('type-flash') === true ? 'on' : 0),
                'type-photo' => ($this->getInput('type-photo') === true ? 'on' : 0),
                'type-music' => ($this->getInput('type-music') === true ? 'on' : 0),
                'type-story' => ($this->getInput('type-story') === true ? 'on' : 0),
                'type-poetry' => ($this->getInput('type-poetry') === true ? 'on' : 0),
                'mode' => $this->getInput('mode')
                ];
                $html = $this->postFASimpleHTMLDOM($data);
                $limit = (is_int($this->getInput('limit')) ? $this->getInput('limit') : 10);
                $this->itemsFromSubmissionList($html, $limit);
                break;
            case 'Browse':
                $data = [
                'cat' => $this->getInput('cat'),
                'atype' => $this->getInput('atype'),
                'species' => $this->getInput('species'),
                'gender' => $this->getInput('gender'),
                'perpage' => 72,
                'rating_general' => ($this->getInput('rating_general') === true ? 'on' : 0),
                'rating_mature' => ($this->getInput('rating_mature') === true ? 'on' : 0),
                'rating_adult' => ($this->getInput('rating_adult') === true ? 'on' : 0)
                ];
                $html = $this->postFASimpleHTMLDOM($data);
                $limit = (is_int($this->getInput('limit-browse')) ? $this->getInput('limit-browse') : 10);
                $this->itemsFromSubmissionList($html, $limit);
                break;
            case 'Journals':
                $html = $this->getFASimpleHTMLDOM($this->getURI());
                $limit = (is_int($this->getInput('limit')) ? $this->getInput('limit') : -1);
                $this->itemsFromJournalList($html, $limit);
                break;
            case 'Single Journal':
                $html = $this->getFASimpleHTMLDOM($this->getURI());
                $this->itemsFromJournal($html);
                break;
            case 'Gallery':
            case 'Scraps':
            case 'Favorites':
            case 'Gallery Folder':
                $html = $this->getFASimpleHTMLDOM($this->getURI());
                $limit = (is_int($this->getInput('limit')) ? $this->getInput('limit') : 10);
                $this->itemsFromSubmissionList($html, $limit);
                break;
        }
    }

    private function postFASimpleHTMLDOM($data)
    {
        $opts = [
                CURLOPT_CUSTOMREQUEST => 'POST',
                CURLOPT_POSTFIELDS => http_build_query($data)
            ];
        $header = [
                'Host: ' . parse_url(self::URI, PHP_URL_HOST),
                'Content-Type: application/x-www-form-urlencoded',
                'Cookie: ' . $this->FA_AUTH_COOKIE
            ];

        $html = getSimpleHTMLDOM($this->getURI(), $header, $opts);
        $html = defaultLinkTo($html, $this->getURI());
        $this->saveLoggedInUser($html);
        return $html;
    }

    private function getFASimpleHTMLDOM($url, $cache = false)
    {
        $header = [
                'Cookie: ' . $this->FA_AUTH_COOKIE
            ];

        if ($cache) {
            $html = getSimpleHTMLDOMCached($url, 86400, $header); // 24 hours
        } else {
            $html = getSimpleHTMLDOM($url, $header);
        }
        $this->saveLoggedInUser($html);
        $html = defaultLinkTo($html, $url);

        return $html;
    }

    private function saveLoggedInUser($html)
    {
        $current_user = $html->find('#my-username', 0);
        if ($current_user !== null) {
            preg_match('/^(?:My FA \( |~)(.*?)(?: \)|)$/', trim($current_user->plaintext), $matches);
            $current_user = $current_user ? $matches[1] : null;
            if ($current_user !== null) {
                $this->saveCacheValue('username', $current_user);
            }
        }
    }

    private function itemsFromJournalList($html, $limit)
    {
        foreach ($html->find('table[id^=jid:]') as $journal) {
            # allows limit = -1 to mean 'unlimited'
            if ($limit-- === 0) {
                break;
            }

            $item = [];

            $this->setReferrerPolicy($journal);

            $item['uri'] = $journal->find('a', 0)->href;
            $item['title'] = html_entity_decode($journal->find('a', 0)->plaintext);
            $item['author'] = $this->getInput('username-journals');
            $item['timestamp'] = strtotime(
                $journal->find('span.popup_date', 0)->plaintext
            );
            $item['content'] = $journal
                ->find('.alt1 table div.no_overflow', 0)
                ->innertext;

            $this->items[] = $item;
        }
    }

    private function itemsFromJournal($html)
    {
        $this->setReferrerPolicy($html);
        $item = [];

        $item['uri'] = $this->getURI();

        $title = $html->find('.journal-title-box .no_overflow', 0)->plaintext;
        $title = html_entity_decode($title);
        $title = trim($title, " \t\n\r\0\x0B" . chr(0xC2) . chr(0xA0));
        $item['title'] = $title;

        $item['author'] = $html->find('.journal-title-box a', 0)->plaintext;
        $item['timestamp'] = strtotime(
            $html->find('.journal-title-box span.popup_date', 0)->plaintext
        );
        $item['content'] = $html->find('.journal-body', 0)->innertext;

        $this->items[] = $item;
    }

    private function itemsFromSubmissionList($html, $limit)
    {
        $cache = ($this->getInput('cache') === true);

        foreach ($html->find('section.gallery figure') as $figure) {
            # allows limit = -1 to mean 'unlimited'
            if ($limit-- === 0) {
                break;
            }

            $item = [];

            $submissionURL = $figure->find('b u a', 0)->href;
            $imgURL = $figure->find('b u a img', 0)->src;

            $item['uri'] = $submissionURL;
            $item['title'] = html_entity_decode(
                $figure->find('figcaption p a[href*=/view/]', 0)->title
            );
            $item['author'] = $figure->find('figcaption p a[href*=/user/]', 0)->title;

            $item['content'] = "<a href=\"$submissionURL\"> <img src=\"{$imgURL}\" referrerpolicy=\"no-referrer\"/></a>";

            if ($this->getInput('full') === true) {
                $submissionHTML = $this->getFASimpleHTMLDOM($submissionURL, $cache);
                if (!$this->isHiddenSubmission($submissionHTML)) {
                    $stats = $submissionHTML->find('.stats-container', 0);
                    $popupDate = $stats->find('.popup_date', 0);
                    if ($popupDate) {
                        $item['timestamp'] = strtotime($popupDate->title);
                    }

                    $var = $submissionHTML->find('.actions a[href^=https://d.facdn]', 0);
                    if ($var) {
                        $item['enclosures'] = [$var->href];
                    }

                    foreach ($stats->find('#keywords a') as $keyword) {
                        $item['categories'][] = $keyword->plaintext;
                    }

                    $previewSrc = $submissionHTML->find('#submissionImg', 0);
                    if ($previewSrc) {
                        $imgURL = 'https:' . $previewSrc->{'data-preview-src'};
                    } else {
                        $imgURL = $submissionHTML->find('[property="og:image"]', 0)->{'content'};
                    }

                    $description = $submissionHTML->find('div.submission-description', 0);
                    if ($description) {
                        $this->setReferrerPolicy($description);
                        $description = trim($description->innertext);
                    } else {
                        $description = '';
                    }

                    $item['content'] = "<a href=\"$submissionURL\"> <img src=\"{$imgURL}\" referrerpolicy=\"no-referrer\"/></a><p>{$description}</p>";
                }
            }

            $this->items[] = $item;
        }
    }

    private function setReferrerPolicy(&$html)
    {
        foreach ($html->find('img') as $img) {
            /*
             * Note: Without the no-referrer policy their CDN sometimes denies requests.
             * We can't control this for enclosures sadly.
             * At least tt-rss adds the referrerpolicy on its own.
             * Alternatively we could not use https for images, but that's not ideal.
             */
            $img->referrerpolicy = 'no-referrer';
        }
    }

    private function isHiddenSubmission($html)
    {
        //Disabled accounts prevents their userpage, gallery, favorites and journals from being viewed.
        //Submissions can require maturity limit or logged-in account.
        $system_message = $html->find('.section-body.alignleft', 0);
        $system_message = $system_message ? $system_message->plaintext : '';

        return str_contains($system_message, 'System Message');
    }
}