ToyMainMenuScene.cpp 14.1 KB
//
//  ToyMainMenuScene.cpp
//  WattsenglishToyApp-mobile
//
//  Created by Katarzyna Kalinowska-Górska on 16/11/2019.
//

#include "ToyMainMenuScene.h"
#include "ToyScalingUtils.h"
#include "ToySimpleButton.h"
#include "ToyGeometryUtils.h"
#include "ToyWorksheetScene.h"
#include "ToySubGameSceneTapNCatch.h"
#include "ToyGameConfigParser.h"
#include "ToyMiscUtils.h"
#include "ToySoundsRepo.h"
#include "ToyTOSAcceptPopupView.h"
#include "ToyTwoStateButton.h"
#include "ToyMiscUtils.h"
#include "ToyRatePromptHandler.h"
#include "HelloWorldScene.h"

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "NativeAndroid/AndroidUtils_cpp.h"
#endif

static float ScreenTransitionDuration = 0.2f;

ToyMainMenuScene* ToyMainMenuScene::create(std::string layoutFilePath){
    ToyMainMenuScene * scene = new (std::nothrow) ToyMainMenuScene();
    if(scene && scene->initWithConfigurationFiles(layoutFilePath))
    {
        scene->autorelease();
        return scene;
    }
    CC_SAFE_DELETE(scene);
    return nullptr;
}

bool ToyMainMenuScene::initWithConfigurationFiles(std::string layoutFilePath){
    if(!ToyParentScene::initWithConfigurationFiles(layoutFilePath))
       {
           return false;
       }
    
    firstEnter = true;

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    addBackButtonListener();
#endif

       return true;
}

void ToyMainMenuScene::onEnter()
{
    ToyParentScene::onEnter();
    if(firstEnter){
        loadLayout(false);
        setupButtons();
        prepareSettingsMenu();

//        ToyRatePromptHandler::countUp();

        showTOSAcceptPopup([&](){
            isShowingLevelPicker = true;
            showToyLevelPickerLayer([&]{isShowingLevelPicker = false; stopAllActions(); ToySoundsRepo::stopAllSounds();
            playMusicIfRequired();});
//            auto introSoundInfo = ToySoundsRepo::introSound();
            auto pickLevelSoundInfo = ToySoundsRepo::pickLevelSound();
            runAction(cocos2d::Sequence::create(/*cocos2d::CallFunc::create(std::bind([&](std::string introSoundFilePath){
                ToySoundsRepo::playSound(introSoundFilePath);
            },introSoundInfo.filePath)),
                                                cocos2d::DelayTime::create(introSoundInfo.soundDuration)
                                                ,*/cocos2d::CallFunc::create(std::bind([&](std::string pickLevelSoundPath){
                ToySoundsRepo::playSound(pickLevelSoundPath);
                repeatPickLevelPrompt();
            },pickLevelSoundInfo.filePath)),
                                                nullptr));
        });
        firstEnter = false;
    } else {
        playMusicIfRequired();
    }
//    ToyRatePromptHandler::presentRatePromptIfApplicable();
}


void ToyMainMenuScene::onExit()
{
    ToyParentScene::onExit();
    ToySoundsRepo::stopAllSounds();
}

void ToyMainMenuScene::playMusicIfRequired(){
    if(ToyMiscUtils::shouldBgMusicPlay()){
        ToySoundsRepo::playMusic(ToySoundsRepo::musicBgFilePath);
    }
}

void ToyMainMenuScene::setupButtons(){
    
    auto settingsButton = dynamic_cast<ToySimpleButton*>(_objects["settingsButton"]);
    settingsButton->setOnTouchEndedCallback([&](const std::string&, cocos2d::ui::Widget::TouchEventType){
        if(!isShowingSettings){
            presentParentalGate([&](){
                hideParentalGate();
                showSettingsMenu();
            }, [&](){
                hideParentalGate();
            });
        } else {
            if(settingsMenu->isShowingParentalGate()){
                settingsMenu->hideParentalGate();
            } else {
                hideSettingsMenu();//WithLevelReset();
            }
        }
    });
    
    prepareBgMusicButton();
    
    auto gameButton1 = dynamic_cast<ToySimpleButton*>(_objects["gameButton1"]);
    gameButton1->setOnTouchEndedCallback([&](const std::string&, cocos2d::ui::Widget::TouchEventType){
        game1Tapped(gameButton1);
    });
    auto worksheetButton1 = dynamic_cast<ToySimpleButton*>(_objects["worksheetButton1"]);
    worksheetButton1->setOnTouchEndedCallback([&](const std::string&, cocos2d::ui::Widget::TouchEventType){
        worksheet1Tapped(worksheetButton1);
    });
    auto gameButton2 = dynamic_cast<ToySimpleButton*>(_objects["gameButton2"]);
    gameButton2->setOnTouchEndedCallback([&](const std::string&, cocos2d::ui::Widget::TouchEventType){
        game2Tapped(gameButton2);
    });
    auto worksheetButton2 = dynamic_cast<ToySimpleButton*>(_objects["worksheetButton2"]);
    worksheetButton2->setOnTouchEndedCallback([&](const std::string&, cocos2d::ui::Widget::TouchEventType){
        worksheet2Tapped(worksheetButton2);
    });
    
    auto exitButton = dynamic_cast<ToySimpleButton*>(_objects["exitButton"]);
    exitButton->setOnTouchEndedCallback([&](const std::string&, cocos2d::ui::Widget::TouchEventType){
            exitTapped(exitButton);
        });
}

void ToyMainMenuScene::prepareSettingsMenu(){
    if(settingsMenu == nullptr){
        isShowingSettings = false;
        auto screenSize = cocos2d::Director::getInstance()->getWinSize();
            settingsMenu = ToySettingsLayer::create(screenSize.width, screenSize.height, CC_CALLBACK_1(ToyMainMenuScene::hideSettingsMenu, this));
        //    addChild(settingsMenu);
            addTouchBlockingLayer(settingsMenu);
            settingsMenu->setLocalZOrder(200);
            moveSettingsButtonToFront(210);
            hideSettingsMenu(false);
            
            settingsMenu->setPosition(cocos2d::Vec2(0, 0));
            settingsMenu->setCascadeOpacityEnabled(true);

        #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
            auto keyboardListener = cocos2d::EventListenerKeyboard::create();
            keyboardListener->onKeyReleased = std::bind([&](cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event, cocos2d::Node* n){
                if(keyCode == cocos2d::EventKeyboard::KeyCode::KEY_BACK){
                    if(ToyMiscUtils::isNodeVisible(n)) {
                        if (settingsMenu->isShowingParentalGate()) {
                            settingsMenu->hideParentalGate();
                        } else {
//                            resumeGame();
                            hideSettingsMenu(true);
                        }
                    }
                }
            }, std::placeholders::_1, std::placeholders::_2, settingsMenu);
            _eventDispatcher->addEventListenerWithSceneGraphPriority(keyboardListener, settingsMenu);
        #endif
    }
}

void ToyMainMenuScene::prepareBgMusicButton(){
    auto bgMusicButton = dynamic_cast<ToyTwoStateButton*>(_objects["backgroundMusicButton"]);
    bgMusicButton->setActive(ToyMiscUtils::shouldBgMusicPlay());
    
    bgMusicButton->setOnTouchEndedCallback([&](const std::string&, cocos2d::ui::Widget::TouchEventType){
        
        auto bgMusicButton = dynamic_cast<ToyTwoStateButton*>(_objects["backgroundMusicButton"]);
        
       if(ToyMiscUtils::shouldBgMusicPlay()){
            ToyMiscUtils::saveBgMusicPlaying(false);
           ToySoundsRepo::stopMusic();
            
            if(bgMusicButton->isActive()){
                bgMusicButton->setActive(false);
            }
            
        } else {
            ToyMiscUtils::saveBgMusicPlaying(true);
            ToySoundsRepo::playMusic(ToySoundsRepo::musicBgFilePath);
            
            if(!bgMusicButton->isActive()){
                bgMusicButton->setActive(true);
            }
        }
    });
    
    // move it as in a horizontal, not vertical menu
    if(ToyScalingUtils::isSmallDevice()){
        auto settingsButton = _objects["settingsButton"];
        auto padding = 20*ToyScalingUtils::scaleAspectFitToDesignIpadProSize();
        bgMusicButton->setPosition(cocos2d::Vec2(settingsButton->getBoundingBox().getMaxX() + padding+bgMusicButton->getBoundingBox().size.width/2, settingsButton->getBoundingBox().getMidY()));
    }
    
}

void ToyMainMenuScene::moveSettingsButtonToFront(int localZOrder){
    auto settingsButton = _objects["settingsButton"];
    settingsButton->removeFromParent(); //remove from the object layer, which it is originally in, as specified in the scene_layout file
    addChild(settingsButton);
    settingsButton->setLocalZOrder(localZOrder);
}

void ToyMainMenuScene::showSettingsMenu(bool animated){
//    ToyRatePromptHandler::presentRatePromptIfApplicable();
    isShowingSettings = true;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    _keyboardListener->setEnabled(false);
#endif
    settingsMenu->prepareForShowing();
    if(animated){
        settingsMenu->stopAllActions();
        settingsMenu->setVisible(true);
        settingsMenu->setOpacity(0);
        settingsMenu->runAction(cocos2d::Sequence::create(cocos2d::FadeTo::create(ToyMiscUtils::StandardAnimationTime, 240),
                cocos2d::CallFunc::create([](){
                    ToyRatePromptHandler::presentRatePromptIfApplicable();
                }), nullptr)); //TODO magic number
    } else {
        settingsMenu->setOpacity(255);
    }
}

void ToyMainMenuScene::hideSettingsMenu(bool animated){
    isShowingSettings = false;
    if(animated){
        settingsMenu->stopAllActions();
        settingsMenu->runAction(cocos2d::Sequence::create(cocos2d::FadeOut::create(ToyMiscUtils::StandardAnimationTime),
                                                          cocos2d::CallFunc::create([&](){
            settingsMenu->setVisible(false);
        }), nullptr));
    } else {
        settingsMenu->setOpacity(0);
        settingsMenu->setVisible(false);
    }
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
        settingsMenu->runAction(cocos2d::CallFunc::create([&](){
            _keyboardListener->setEnabled(true);
        }));
    #endif
}

void ToyMainMenuScene::settingsButtonTapped(cocos2d::Ref* pSender){
    showSettingsMenu();
}

void ToyMainMenuScene::game1Tapped(cocos2d::Ref* pSender){
    ToyGameConfigParser parser("common/games/game1/gconfig.gcf");
    std::string layoutFile = ToyScalingUtils::getDeviceAspectRatio() < 1.8f ? "graphics/game1/scene_layout.scl" : "graphics/game1/scene_layout_long.scl";
    auto newScene = parser.createGameScene(1, layoutFile);
    cocos2d::Director::getInstance()->pushScene(newScene);
//    cocos2d::Director::getInstance()->pushScene(cocos2d::TransitionCrossFade::create(ScreenTransitionDuration, newScene));
}

void ToyMainMenuScene::game2Tapped(cocos2d::Ref* pSender){
    ToyGameConfigParser parser("common/games/game2/gconfig.gcf");
    std::string layoutFile = ToyScalingUtils::getDeviceAspectRatio() < 1.8f ? "graphics/game2/scene_layout.scl" : "graphics/game2/scene_layout_long.scl";
    auto newScene = parser.createGameScene(2, layoutFile);
    cocos2d::Director::getInstance()->pushScene(newScene);
//    cocos2d::Director::getInstance()->pushScene(cocos2d::TransitionCrossFade::create(ScreenTransitionDuration, newScene));
}

void ToyMainMenuScene::worksheet1Tapped(cocos2d::Ref* pSender){
    auto level = ToyMiscUtils::lastLevel();
    std::string scenarioPath = "common/worksheet1/scenario_3.sc";
    std::string sceneLayoutPath = "graphics/worksheet1/scene_layout.scl";
    if(level == ToyMiscUtils::Level::CHILD){
        scenarioPath = "common/worksheet1/scenario_1.sc";
        sceneLayoutPath = "graphics/worksheet1/scene_layout1.scl";
    } else if(level == ToyMiscUtils::Level::TEEN){
        scenarioPath = "common/worksheet1/scenario_2.sc";
    }
    auto newScene = ToyWorksheetScene::create(sceneLayoutPath, scenarioPath); //TODO put in json
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
if(androidUtils_osApiVersion() >= 28) {
    newScene->setAndroidBackButtonDisabled(true);
}
#endif

    cocos2d::Director::getInstance()->pushScene(newScene);
//    cocos2d::Director::getInstance()->pushScene(cocos2d::TransitionCrossFade::create(ScreenTransitionDuration, newScene));
}

void ToyMainMenuScene::worksheet2Tapped(cocos2d::Ref* pSender){
    auto level = ToyMiscUtils::lastLevel();
    std::string scenarioPath = "common/worksheet2/scenario_3.sc";
    std::string layoutPAth = "graphics/worksheet2/scene_layout3.scl";
    if(level == ToyMiscUtils::Level::CHILD){
        scenarioPath = "common/worksheet2/scenario_1.sc";
        layoutPAth = "graphics/worksheet2/scene_layout1.scl";
    } else if(level == ToyMiscUtils::Level::TEEN){
        scenarioPath = "common/worksheet2/scenario_2.sc";
        layoutPAth = "graphics/worksheet2/scene_layout2.scl";
    }
    auto newScene = ToyWorksheetScene::create(layoutPAth, scenarioPath); //TODO put in json
    cocos2d::Director::getInstance()->pushScene(newScene);
//    cocos2d::Director::getInstance()->pushScene(cocos2d::TransitionCrossFade::create(ScreenTransitionDuration, newScene));
}

void ToyMainMenuScene::exitTapped(cocos2d::Ref* pSender){
//    cocos2d::Director::getInstance()->end();
    ToyMiscUtils::showAppCloseConfirmDialog([&](){
    });
}

void ToyMainMenuScene::showTOSAcceptPopup(std::function<void()> onAccept){
    if(ToyMiscUtils::wasTOSAccepted()){
//        gameState->tosAcceptMenuShown = false;
        onAccept();
    } else {
//        gameState->tosAcceptMenuShown = true;
        auto tosPopup = ToyTOSAcceptPopupView::create(std::bind([&](std::function<void()>f){
            ToyMiscUtils::saveTOSAccepted();
//            gameState->tosAcceptMenuShown = false;
            f();}, onAccept));
        
        addTouchBlockingLayer(tosPopup);
        tosPopup->setLocalZOrder(500);
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
        auto keyboardListener = cocos2d::EventListenerKeyboard::create();
        keyboardListener->onKeyReleased = std::bind([&](cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event, ToyTOSAcceptPopupView* n){
            if(keyCode == cocos2d::EventKeyboard::KeyCode::KEY_BACK){
                if(ToyMiscUtils::isNodeVisible(n)){
                    if (n->isShowingParentalGate()) {
                       n->hideParentalGate();
                    } else {


                        cocos2d::Director::getInstance()->end();
                        //auto scene = HelloWorld::createScene();
                        //cocos2d::Director::getInstance()->replaceScene(scene);


                    }
                }
            }
        }, std::placeholders::_1, std::placeholders::_2, tosPopup);
        _eventDispatcher->addEventListenerWithSceneGraphPriority(keyboardListener, tosPopup);
#endif
    }
}