| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE library.
 -    Copyright (c) 2017 - ROLI Ltd.
 - 
 -    JUCE is an open source library subject to commercial or open-source
 -    licensing.
 - 
 -    By using JUCE, you agree to the terms of both the JUCE 5 End-User License
 -    Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
 -    27th April 2017).
 - 
 -    End User License Agreement: www.juce.com/juce-5-licence
 -    Privacy Policy: www.juce.com/juce-5-privacy-policy
 - 
 -    Or: You may also use this code under the terms of the GPL v3 (see
 -    www.gnu.org/licenses).
 - 
 -    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
 -    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
 -    DISCLAIMED.
 - 
 -   ==============================================================================
 - */
 - 
 - //==============================================================================
 - class VoicePurchases      : private InAppPurchases::Listener
 - {
 - public:
 -     //==============================================================================
 -     struct VoiceProduct
 -     {
 -         const char* identifier;
 -         const char* humanReadable;
 -         bool isPurchased, priceIsKnown, purchaseInProgress;
 -         String purchasePrice;
 -     };
 - 
 -     //==============================================================================
 -     VoicePurchases (AsyncUpdater& asyncUpdater)
 -          : guiUpdater (asyncUpdater)
 -     {
 -         voiceProducts = Array<VoiceProduct>(
 -                          {VoiceProduct {"robot", "Robot",   true,   true,  false, "Free" },
 -                           VoiceProduct {"jules",  "Jules",  false,  false, false, "Retrieving price..." },
 -                           VoiceProduct {"fabian", "Fabian", false,  false, false, "Retrieving price..." },
 -                           VoiceProduct {"ed",     "Ed",     false,  false, false, "Retrieving price..." },
 -                           VoiceProduct {"lukasz", "Lukasz", false,  false, false, "Retrieving price..." },
 -                           VoiceProduct {"jb",     "JB",     false,  false, false, "Retrieving price..." } });
 -     }
 - 
 -     ~VoicePurchases()
 -     {
 -         InAppPurchases::getInstance()->removeListener (this);
 -     }
 - 
 -     //==============================================================================
 -     VoiceProduct getPurchase (int voiceIndex)
 -     {
 -         if (! havePurchasesBeenRestored)
 -         {
 -             havePurchasesBeenRestored = true;
 -             InAppPurchases::getInstance()->addListener (this);
 - 
 -             InAppPurchases::getInstance()->restoreProductsBoughtList (true);
 -         }
 - 
 -         return voiceProducts[voiceIndex];
 -     }
 - 
 -     void purchaseVoice (int voiceIndex)
 -     {
 -         if (havePricesBeenFetched && isPositiveAndBelow (voiceIndex, voiceProducts.size()))
 -         {
 -             auto& product = voiceProducts.getReference (voiceIndex);
 - 
 -             if (! product.isPurchased)
 -             {
 -                 purchaseInProgress = true;
 - 
 -                 product.purchaseInProgress = true;
 -                 InAppPurchases::getInstance()->purchaseProduct (product.identifier, false);
 - 
 -                 guiUpdater.triggerAsyncUpdate();
 -             }
 -         }
 -     }
 - 
 -     StringArray getVoiceNames() const
 -     {
 -         StringArray names;
 - 
 -         for (auto& voiceProduct : voiceProducts)
 -             names.add (voiceProduct.humanReadable);
 - 
 -         return names;
 -     }
 - 
 -     bool isPurchaseInProgress() const noexcept { return purchaseInProgress; }
 - 
 - private:
 -     //==============================================================================
 -     void productsInfoReturned (const Array<InAppPurchases::Product>& products) override
 -     {
 -         if (! InAppPurchases::getInstance()->isInAppPurchasesSupported())
 -         {
 -             for (auto idx = 1; idx < voiceProducts.size(); ++idx)
 -             {
 -                 auto& voiceProduct = voiceProducts.getReference (idx);
 - 
 -                 voiceProduct.isPurchased  = false;
 -                 voiceProduct.priceIsKnown = false;
 -                 voiceProduct.purchasePrice = "In-App purcahses unavailable";
 -             }
 - 
 -             AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
 -                                               "In-app purchase is unavailable!",
 -                                               "In-App purchases are not available. This either means you are trying "
 -                                               "to use IAP on a platform that does not support IAP or you haven't setup "
 -                                               "your app correctly to work with IAP.",
 -                                               "OK");
 -         }
 -         else
 -         {
 -             for (auto product : products)
 -             {
 -                 auto idx = findVoiceIndexFromIdentifier (product.identifier);
 - 
 -                 if (isPositiveAndBelow (idx, voiceProducts.size()))
 -                 {
 -                     auto& voiceProduct = voiceProducts.getReference (idx);
 - 
 -                     voiceProduct.priceIsKnown = true;
 -                     voiceProduct.purchasePrice = product.price;
 -                 }
 -             }
 - 
 -             AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
 -                                               "Your credit card will be charged!",
 -                                               "You are running the sample code for JUCE In-App purchases. "
 -                                               "Although this is only sample code, it will still CHARGE YOUR CREDIT CARD!",
 -                                               "Understood!");
 -         }
 - 
 -         guiUpdater.triggerAsyncUpdate();
 -     }
 - 
 -     void productPurchaseFinished (const PurchaseInfo& info, bool success, const String&) override
 -     {
 -         purchaseInProgress = false;
 - 
 -         auto idx = findVoiceIndexFromIdentifier (info.purchase.productId);
 - 
 -         if (isPositiveAndBelow (idx, voiceProducts.size()))
 -         {
 -             auto& voiceProduct = voiceProducts.getReference (idx);
 - 
 -             voiceProduct.isPurchased = success;
 -             voiceProduct.purchaseInProgress = false;
 -             guiUpdater.triggerAsyncUpdate();
 -         }
 -         else
 -         {
 -             // On failure Play Store will not tell us which purchase failed
 - 
 -             for (auto& voiceProduct : voiceProducts)
 -                 voiceProduct.purchaseInProgress = false;
 - 
 -             guiUpdater.triggerAsyncUpdate();
 -         }
 -     }
 - 
 -     void purchasesListRestored (const Array<PurchaseInfo>& infos, bool success, const String&) override
 -     {
 -         if (success)
 -         {
 -             for (auto& info : infos)
 -             {
 -                 auto idx = findVoiceIndexFromIdentifier (info.purchase.productId);
 - 
 -                 if (isPositiveAndBelow (idx, voiceProducts.size()))
 -                 {
 -                     auto& voiceProduct = voiceProducts.getReference (idx);
 - 
 -                     voiceProduct.isPurchased = true;
 -                 }
 -             }
 - 
 -             guiUpdater.triggerAsyncUpdate();
 -         }
 - 
 -         if (! havePricesBeenFetched)
 -         {
 -             havePricesBeenFetched = true;
 -             StringArray identifiers;
 - 
 -             for (auto& voiceProduct : voiceProducts)
 -                 identifiers.add (voiceProduct.identifier);
 - 
 -             InAppPurchases::getInstance()->getProductsInformation (identifiers);
 -         }
 -     }
 - 
 -     //==============================================================================
 -     int findVoiceIndexFromIdentifier (String identifier) const
 -     {
 -         identifier = identifier.toLowerCase();
 - 
 -         for (auto i = 0; i < voiceProducts.size(); ++i)
 -             if (String (voiceProducts.getReference (i).identifier) ==  identifier)
 -                 return i;
 - 
 -         return -1;
 -     }
 - 
 -     //==============================================================================
 -     AsyncUpdater& guiUpdater;
 -     bool havePurchasesBeenRestored = false, havePricesBeenFetched = false, purchaseInProgress = false;
 -     Array<VoiceProduct> voiceProducts;
 - 
 -     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VoicePurchases)
 - };
 
 
  |