Dexmaster / Checkout Free Books (Amazon)

// ==UserScript==
// @name        Checkout Free Books (Amazon)
// @namespace   openuserjs.org
// @description Checkout Free Books on Amazon Search Page, opens all books with 3.59+ rating. Then adds them if free and close later. Booklist saves to books (Works on every Amazon Search Page! Also Closes ALL "Thanks, %nickname%!" tabs! You are WARNED!)
// @include    http://www.amazon.com/*/dp/*
// @include    https://www.amazon.com/*/dp/*
// @include    https://www.amazon.com/gp/digital/fiona/thank-you*
// @include    https://www.amazon.com/kindle-dbs/thankYouPage*
// @include    https://www.amazon.com/gp/digital/fiona/clarification/purchased*
// @include    http://www.amazon.com/s/*
// @include    https://www.amazon.com/s/*
// @include    http://www.amazon.com/gp/search/*
// @include    https://www.amazon.com/gp/search/*
// @include    http://www.amazon.com/gp/product/*
// @include    https://www.amazon.com/gp/product/*
// @author     Dexmaster
// @version    2.16
// @grant      GM_openInTab
// @grant      GM_getValue
// @grant      GM_setValue
// @run-at     document-end
// ==/UserScript==
(function() {
    'use strict';
    if (window.free_booker === undefined) {
        window.free_booker = {
            free: !document.querySelector('#giftButtonStack'),
            havent_bought: !(document.querySelector('#ebooksInstantOrderUpdate_feature_div .a-section') || document.querySelector('.iou_div')),
            device_list: document.querySelector('select#deliverTo.a-native-dropdown'),
            buy_button: document.querySelector('#one-click-button'),
            stars: document.querySelector('.acrPopover'),
            thank_you: document.querySelector('.a-alert-success h1'),
            books_anch: [].slice.call(document.querySelectorAll('#atfResults .s-item-container a.a-link-normal.s-access-detail-page')).reverse(),
            books_prices: [].slice.call(document.querySelectorAll('#resultsCol #s-results-list-atf a .s-price')).reverse(),
            next_link: document.querySelector('#pagn span.pagnRA a#pagnNextLink'),
            first_link: document.querySelector('div#pagn span.pagnLink a'),
            double_buy: document.querySelector('.flexBoxContent'),
            stars_float: 3.3,
            stars_minimum: 2.99, // YOUR BOOK STARS MINIMUM
            op1_name: 'Kindle Cloud Reader', // option script will chose first in our case Kindle Cloud Reader
            op2_name: 'Kindle for PC', // option script will chose as alternative
            op3_name: '*YOUR_ALTERNATIVE*', // option script will chose as third alternative
            wait_ms: 3000,
            wait_low_ms: 5000,
            counter: 0, // counter of free books
            looper: true, // Loop when non-free reached???
            get_ASIN: function(href_str) {
                if (href_str.indexOf('/product/') > -1) {
                    return href_str.substring(href_str.indexOf('/product/') + 9, href_str.indexOf('?')); // LET'S GET SOME ASIN
                } else {
                    return href_str.substring(href_str.indexOf('/dp/') + 4, href_str.indexOf('/ref')); // LEGACY ASIN STRING
                }
            },
            ad_free_book: function(href_str) {
                var asin_str = window.free_booker.get_ASIN(href_str),
                    books = GM_getValue('books', []);
                if (books.length === 0) {
                    books[0] = asin_str; // FIRST BOOK IN ARRAY ))
                } else {
                    if (books.indexOf(asin_str) < 0) {
                        books.push(asin_str); // ADD BOOK TO ARRAY
                    }
                }
                if (typeof books === 'object') {
                    GM_setValue('books', books); // SAVE BOOK ARRAY TO STORAGE
                }
            },
            parse_href: function(elem, price) {
                var href_str = elem.href,
                    asin_str = window.free_booker.get_ASIN(href_str),
                    books = GM_getValue('books', []),
                    back_col = '#FFDDDD',
                    parent_el = elem.parentElement.parentElement;
                if ((parseFloat(price) === 0) && (typeof books === 'object')) {
                    back_col = '#DDFFDD';
                    if (books.indexOf(asin_str) < 0) {
                        GM_openInTab(href_str, true); // OPEN BOOK PAGE
                        back_col = '#DDDDFF';
                        clearTimeout(window.free_booker.timeout);
                    }
                }
                parent_el.style.backgroundColor = back_col; // COLOR UP PARRENT ELEMENT
                parent_el.scrollIntoView(false);
                window.free_booker.timeout = window.setTimeout(window.free_booker.ckeckout_book, window.free_booker.wait_low_ms + Math.random() * window.free_booker.wait_low_ms); // NEXT LOOP
            },
            select_opt: function(opt_name) {
                var selected = false,
                    i;
                for (i = 0; i < window.free_booker.device_list.options.length; i++) {
                    if ((window.free_booker.device_list.options[i].text.indexOf(opt_name) > -1) && (window.free_booker.stars_float > window.free_booker.stars_minimum)) {
                        window.free_booker.device_list.selectedIndex = i;
                        window.free_booker.buy_button.click();
                        selected = true;
                        break;
                    }
                }
                return selected;
            },
            ckeckout_book: function() {
                if (window.free_booker.device_list !== null) { // BOOK PAGE
                    if (window.free_booker.free && window.free_booker.havent_bought) { // FREE BOOK & HAVENT BOUGHT
                        if (!!window.free_booker.stars) {
                            if (!!window.free_booker.stars.title) {
                                window.free_booker.stars_float = parseFloat(window.free_booker.stars.title);
                            }
                        }
                        if (!window.free_booker.select_opt(window.free_booker.op1_name)) { // CHECK ALL OPTIONS IF NONE EXISTS CLOSE WINDOW
                            if (!window.free_booker.select_opt(window.free_booker.op2_name)) {
                                if (!window.free_booker.select_opt(window.free_booker.op3_name)) {
                                    window.free_booker.close();
                                }
                            }
                        }
                    } else {
                        if (!window.free_booker.havent_bought) { // IF WE OPENED A BOOK WE HAVE BOUGHT
                            window.free_booker.ad_free_book(window.location.href); // ADD THIS BOOK TO STORAGE
                        }
                        window.free_booker.close();
                    }
                } else {
                    if (!!window.free_booker.thank_you) { // IT'S THANKS PAGE
                        if (window.free_booker.thank_you.innerHTML.trim().substring(0, 6) === 'Thanks') { // ARE YOU SURE?
                            window.free_booker.close(); // CLOSE THANKS PAGE
                            
                        }
                    }
                    if (window.free_booker.counter === 0) {
                        window.free_booker.books_prices.forEach(function(el, i) {
                            var clean_el = el.innerHTML.replace(/\$/g, ''); // CLEANING PRICE
                            window.free_booker.books_prices[i] = clean_el;
                            if (parseFloat(clean_el) === 0) {
                                window.free_booker.counter += 1; // COUNTING FREE BOOKS
                            }
                        });
                    }
                    if (window.free_booker.counter > 0) { // IT'S PAGE WITH BOOKS (SEARCH PAGE)
                        if (window.free_booker.books_anch.length > 0) {
                            var elemn = window.free_booker.books_anch.pop(),
                                price = window.free_booker.books_prices.pop();
                            window.free_booker.parse_href(elemn, price); // LET'S CHECK ONE ELEMENT
                        } else {
                            if (!!window.free_booker.next_link) {
                                window.location.href = window.free_booker.next_link.href; // NEXT PAGE
                            }
                        }
                    } else {
                        if (!!window.free_booker.first_link && window.free_booker.looper) { // IF LOOPER TRUE AND THERE EXIST FIRST PAGE
                            window.location.href = window.free_booker.first_link.href; // GOTO FIRST PAGE
                        } else { // IF LOOPER FALSE
                            clearTimeout(window.free_booker.timeout); // JUST STOP
                        }
                    }
                    if (!!window.free_booker.double_buy) { // IT'S DOUBLE BOUGHT PAGE
                        window.free_booker.close(); // CLOSE DOUBLE BOUGHT WINDOW
                    }
                }
            },
            listener: function() { // TRIGGER SCRIPT ON CONTENT LOADED
                console.log('Checkout Free Books (Amazon) Loaded');
                window.free_booker.timeout = window.setTimeout(window.free_booker.ckeckout_book, window.free_booker.wait_ms + Math.random() * window.free_booker.wait_ms);
            },
            close: function() {
                var win = window.open('', '_self');
                window.close();
                win.close();
                return false;
            },
            timeout: null
        };
        window.free_booker.listener();
    }
}());