HalloweenParentScene.cpp 9.21 KB
//
//  HalloweenParentScene.cpp
//  SteveMaggieCpp
//
//  Created by Katarzyna Kalinowska-Górska on 16.05.2017.
//
//

#include <stdio.h>
#include "HalloweenParentScene.h"
#include "HLayoutParser.h"
#include "HSoundUtils.h"
#include "HalloweenSimpleButton.h"
//#include "HTwoStateButton.h"
#include "HMathUtils.h"
#include "HStringUtils.h"
#include "HResourceUtilities.h"


HalloweenParentScene* HalloweenParentScene::create(std::string layoutFilePath)
{
    HalloweenParentScene * scene = new (std::nothrow) HalloweenParentScene();
    if(scene && scene->initWithConfigurationFiles(layoutFilePath))
    {
        scene->autorelease();
        return scene;
    }
    CC_SAFE_DELETE(scene);
    return nullptr;
}
    
bool HalloweenParentScene::initWithConfigurationFiles(std::string layoutFilePath)
{
    if(!HSceneWithUtils::init())
    {
        return false;
    }
    
    _layoutFilePath = layoutFilePath;
    _loadFromAssets = false;
 
    _layers.clear();
    _objects.clear();
    
    _layoutLoaded = false;
    
    _isHandlingTouches = false;
    this->clearTouchHandlers();
    this->resetLastUserTouchTimes();

    return true;
}

void HalloweenParentScene::reloadLayoutClean()
{
    this->removeAllChildren();
    _layers.clear();
    _objects.clear();
    
    _isHandlingTouches = false;
    this->clearTouchHandlers();
    this->resetLastUserTouchTimes();
    
    this->loadLayout(true);
}

void HalloweenParentScene::loadLayout(bool forceLoad)
{
    if(!this->_layoutLoaded || forceLoad){
     
        _layoutLoaded = false;
     
        if (_loadFromAssets && cocos2d::FileUtils::getInstance()->isFileExist(this->_layoutFilePath)) {
            auto& HLayoutParser = HLayoutParser::getInstance();
            HLayoutParser.loadLayoutFromJSONFile(this->_layoutFilePath, this);
            this->_layoutLoaded = true;
        }
        else if(!_loadFromAssets){
            auto& HLayoutParser = HLayoutParser::getInstance();
            HLayoutParser.loadLayoutFromDownloadedJSONFile(this->_layoutFilePath, this);
            this->_layoutLoaded = true;
        }
        
    }
}

void HalloweenParentScene::setLoadFromAssets(bool loadFromAssets)
{
    _loadFromAssets = loadFromAssets;
}

// overrides

void HalloweenParentScene::onEnter()
{
    this->configureTouchHandlers();
//    this->configureTransitionListeners();
    HSceneWithUtils::onEnter();
    this->playBackgroundMusic(true);
}

void HalloweenParentScene::onExit()
{
    this->stopBackgroundMusic(false);
    HSceneWithUtils::onExit();
}


//void HalloweenParentScene::configureTransitionListeners() //TODO check if it works. remove somewhere later the vent listeners? leaks?
//{
//    _eventDispatcher->addCustomEventListener("game_on_hide", CC_CALLBACK_1(HalloweenParentScene::onGameHide, this));
//    _eventDispatcher->addCustomEventListener("game_on_show", CC_CALLBACK_1(HalloweenParentScene::onGameShow, this));
//}

// object config & handlers

bool HalloweenParentScene::touchHandlerForWidget(std::string objectName, cocos2d::ui::Widget::TouchEventType touchEventType)
{
    if(objectName == "backButton" && touchEventType == cocos2d::ui::Widget::TouchEventType::ENDED){
        HSoundUtils::stopMusic();
        HSoundUtils::stopAllSounds();
        cocos2d::Director::getInstance()->popScene();
        _sceneDismissCallback();
        return true;
    }
    
    return false;
}
    
void HalloweenParentScene::disableButton(std::string buttonName)
{
    auto object = this->getObjectByName(buttonName);
    auto button = dynamic_cast<HalloweenSimpleButton*>(object);
    if(button && button->getOpacity() != 0){
        button->setEnabled(false);
        button->setOpacity(128);
        for(auto child : button->getChildren()){
            child->setOpacity(128);
        }
    }
}
    
void HalloweenParentScene::enableButton(std::string buttonName)
{
    auto object = this->getObjectByName(buttonName);
    auto button = dynamic_cast<HalloweenSimpleButton*>(object);
    if(button){
        button->setEnabled(true);
        button->setOpacity(255);
        for(auto child : button->getChildren()){
            child->setOpacity(255);
        }
    }
}
    
// fast forward button convenience

//void HalloweenParentScene::disableFastForwardButton()
//{
//    this->disableButton("fastForwardButton");
//}
//
//void HalloweenParentScene::enableFastForwardButton()
//{
//    this->enableButton("fastForwardButton");
//}

// touch handlers
    
void HalloweenParentScene::configureTouchHandlers()
{
    auto touchListener = cocos2d::EventListenerTouchOneByOne::create();
    
    touchListener->onTouchBegan = [&](cocos2d::Touch* touch, cocos2d::Event* event) -> bool{
        
        _isHandlingTouches = true;
        for(auto handler : _touchBeganHandlers){
            handler.second(touch, event);
        }
        
        _isHandlingTouches = false;
        this->filterTouchHandlers();
        
        return true;
    };
    
    touchListener->onTouchMoved = [&](cocos2d::Touch* touch, cocos2d::Event* event){
    
        _isHandlingTouches = true;
        _lastUserTouchMovedTime = cocos2d::utils::getTimeInMilliseconds();
    
        for(auto handler : _touchMovedHandlers){
            handler.second(touch, event);
        }
        
        _isHandlingTouches = false;
        this->filterTouchHandlers();
    };

    touchListener->onTouchEnded = [&](cocos2d::Touch* touch, cocos2d::Event* event){
    
        _isHandlingTouches = true;
        _lastUserTouchEndedTime = cocos2d::utils::getTimeInMilliseconds();
        
        for(auto handler : _touchEndedHandlers){
            handler.second(touch, event);
        }
        
        _isHandlingTouches = false;
        this->filterTouchHandlers();
    };

    _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
 }

void HalloweenParentScene::filterTouchHandlers()
{
    for(auto pair : _touchHandlersToRemove){
        this->removeTouchHandler(pair.first, pair.second);
    }
    
    _touchHandlersToRemove.clear();
}

void HalloweenParentScene::clearTouchHandlers()
{
     _touchBeganHandlers.clear();
     _touchMovedHandlers.clear();
     _touchEndedHandlers.clear();
 }
     
void HalloweenParentScene::addTouchHandler(std::string key, TouchHandlerFunction touchHandler, TouchHandlerType touchType)
{
    auto handlersArray = this->pickTouchHandlersContainer(touchType);
    
    if(handlersArray){
        handlersArray->insert({key, touchHandler});
    }
}
     
void HalloweenParentScene::removeTouchHandler(std::string touchHandlerKey, TouchHandlerType touchHandlerType)
{
    if(!_isHandlingTouches){
        auto handlersArray = this->pickTouchHandlersContainer(touchHandlerType);
        if(handlersArray){
            handlersArray->erase(touchHandlerKey);
         }
    }
    else {
     _touchHandlersToRemove.insert({touchHandlerKey, touchHandlerType});
    }
}
     
std::map<std::string,TouchHandlerFunction>* HalloweenParentScene::pickTouchHandlersContainer(TouchHandlerType touchHandlerType)
{
    std::map<std::string,TouchHandlerFunction>* handlersArray = NULL;
    switch(touchHandlerType){
        case TouchHandlerType::TOUCHES_BEGAN:
            handlersArray = &_touchBeganHandlers;
            break;
        case TouchHandlerType::TOUCHES_MOVED:
            handlersArray = &_touchMovedHandlers;
            break;
        case TouchHandlerType::TOUCHES_ENDED:
            handlersArray = &_touchEndedHandlers;
            break;
        default:
            break;
    }
    
    return handlersArray;
}
     
long long HalloweenParentScene::getLastScreenTouchTime()
{
    if(_lastUserTouchEndedTime != -1 && _lastUserTouchMovedTime != -1){
        return MAX(_lastUserTouchEndedTime, _lastUserTouchMovedTime);
    } else {
        return _lastUserTouchMovedTime; // if moved is null, ended must be null as well
    }
}
    
void HalloweenParentScene::resetLastUserTouchTimes()
{
    _lastUserTouchEndedTime = -1;
    _lastUserTouchMovedTime = -1;
}
 
 // presenting the endscene
     
//void HalloweenParentScene::presentEndscene()
//{
//    //TODO fetch from the server and configure differently
//    const char* scenarioFiles[2] = {"common/end_subscene/endscene_scenario1.sc", "common/end_subscene/endscene_scenario2.sc"};
//    const char* layoutFiles[2] = {"common/end_subscene/endscene_layout1.scl", "common/end_subscene/endscene_layout2.scl"};
//
//    auto endsceneVersion = HMathUtils::getRandomInt(0, 1);
//
//    std::string chosenLayoutFile = layoutFiles[endsceneVersion];
//    std::string chosenScenarioFile = scenarioFiles[endsceneVersion];
//
//    chosenLayoutFile = HResourceUtilities::getInstance().getFullPathForDownloadedFile(chosenLayoutFile);
//    chosenScenarioFile = HResourceUtilities::getInstance().getFullPathForDownloadedFile(chosenScenarioFile, false);
//
//    auto endscene = EndScene::create(chosenLayoutFile, chosenScenarioFile, _layoutFilePath, _scenarioFilePath);
//
//    cocos2d::Director::getInstance()->replaceScene(endscene);
// }

// layout parse delegate
void HalloweenParentScene::addLayer(cocos2d::Layer* layer)
{
    _layers.push_back(layer);
}

void HalloweenParentScene::addObject(std::string objectName, cocos2d::Node* object)
{
    _objects.insert({objectName, object});
}

void HalloweenParentScene::addNewNodeToObjectLayer(cocos2d::Node* newNode){
    if(_layers.size() > 0){
        _layers[_layers.size()-1]->addChild(newNode);
    }
}