angular.module("personal-banker").directive("interactiveTutorial", function(env, $timeout, $document, $q, $rootScope, UserTip) {
return {
restrict: "E",
templateUrl: env.templates["amf-ui-library/templates/directives/interactive_tutorial.html"],
link: function(scope, elem, attrs) {
elem.on("click", function(e) {
return e.stopPropagation();
});
scope.currentStep = 0;
$rootScope.$on("$stateChangeSuccess", function(e) {
if (scope.tutorialActive && !scope.tutorialData.allowStateChange) {
return scope.stopTutorial();
}
});
scope.$on("it:startTutorial", function(e, tutorialData) {
return scope.startTutorial(tutorialData);
});
scope.$on("it:stopTutorial", function() {
return scope.stopTutorial();
});
scope.$on("it:nextStep", function() {
return scope.nextStep();
});
scope.$on("it:previousStep", function() {
return scope.previousStep();
});
scope.$on("tb:finishedTutorial", function() {
return scope.setTutorialTipAsDone();
});
scope.setTutorialTipAsDone = function() {
return UserTip.hide(scope.tutorialData.name);
};
scope.startTutorial = function(tutorialData) {
var onTutorialStart;
$rootScope.$broadcast("it:tutorialStarted");
scope.tutorialData = tutorialData;
scope.tutorialActive = true;
scope.currentStep = 0;
onTutorialStart = scope.tutorialData.onTutorialStart;
if (onTutorialStartFunc) {
onTutorialStartFunc();
}
return scope.nextStep();
};
scope.stopTutorial = function() {
var onLeaveHighlightFunc, onTutorialStopFunc;
scope.tutorial = null;
scope.tutorialActive = false;
scope.showSpotlight = false;
scope.showTutorialBox = false;
onLeaveHighlightFunc = scope.tutorialData.steps[scope.currentStep - 1].onLeaveHighlight;
if (onLeaveHighlightFunc) {
onLeaveHighlightFunc();
}
onTutorialStopFunc = scope.tutorialData.onTutorialStop;
if (onTutorialStopFunc) {
onTutorialStopFunc();
}
return $rootScope.$broadcast("it:tutorialStopped");
};
scope.nextStep = function() {
var data, onLeaveHighlightFunc;
scope.currentStep++;
if (scope.currentStep > scope.tutorialData.steps.length) {
scope.currentStep--;
return;
}
scope.showTutorialBox = false;
if (scope.currentStep !== 1) {
onLeaveHighlightFunc = scope.tutorialData.steps[scope.currentStep - 2].onLeaveHighlight;
}
if (onLeaveHighlightFunc) {
onLeaveHighlightFunc();
}
data = scope.tutorialData.steps[scope.currentStep - 1];
data = scope.tutorialData.steps[scope.currentStep - 1];
return $timeout((function() {
return scope.highlightElement(data);
}), 50);
};
scope.previousStep = function() {
var data, onLeaveHighlightFunc;
scope.currentStep--;
if (scope.currentStep === 0) {
scope.currentStep++;
return;
}
onLeaveHighlightFunc = scope.tutorialData.steps[scope.currentStep].onLeaveHighlight;
if (onLeaveHighlightFunc) {
onLeaveHighlightFunc();
}
scope.showTutorialBox = false;
data = scope.tutorialData.steps[scope.currentStep - 1];
return $timeout((function() {
return scope.highlightElement(data);
}), 50);
};
scope.asyncEnsureSpotInViewport = function(scrollTop, pHeight, spot, $mainContentWrapper) {
var adjustedValues, animationOpts, bottomOfSpot, bottomOfViewport, deferred, scrollDuration, scrollTo;
deferred = $q.defer();
adjustedValues = {};
scrollDuration = 500;
bottomOfSpot = spot.y + (spot.radius * 2);
bottomOfViewport = pHeight + scrollTop;
animationOpts = {
duration: scrollDuration,
complete: function() {
return deferred.resolve(adjustedValues);
}
};
scrollTo = scrollTop;
if (spot.y < 0) {
adjustedValues.y = 0;
scrollTo = scrollTop + spot.y;
} else if (bottomOfSpot > pHeight) {
adjustedValues.y = pHeight - (spot.radius * 2);
scrollTo = scrollTop + (bottomOfSpot - pHeight);
} else {
animationOpts.duration = 0;
}
$mainContentWrapper.animate({
scrollTop: scrollTo
}, animationOpts);
return deferred.promise;
};
scope.calculateSpotAdjustments = function(adjustments, tMidPtCoords, spot) {
var adjustedSpot, align;
if (adjustments.maxDiameter >= spot.dim) {
return spot;
}
adjustedSpot = {};
align = adjustments.align || "center";
switch (align) {
case "left":
adjustedSpot.dim = adjustments.maxDiameter;
adjustedSpot.radius = adjustments.maxDiameter / 2;
adjustedSpot.x = spot.x;
adjustedSpot.y = spot.y + ((spot.dim / 2) - (adjustments.maxDiameter / 2));
break;
case "center":
adjustedSpot.dim = adjustments.maxDiameter;
adjustedSpot.radius = adjustments.maxDiameter / 2;
adjustedSpot.x = spot.x + ((spot.dim / 2) - (adjustments.maxDiameter / 2));
adjustedSpot.y = spot.y + ((spot.dim / 2) - (adjustments.maxDiameter / 2));
break;
case "right":
adjustedSpot.dim = adjustments.maxDiameter;
adjustedSpot.radius = adjustments.maxDiameter / 2;
adjustedSpot.x = spot.x + spot.dim - adjustments.maxDiameter;
adjustedSpot.y = spot.y + ((spot.dim / 2) - (adjustments.maxDiameter / 2));
}
return adjustedSpot;
};
return scope.highlightElement = function(data) {
var $mainContentWrapper, $page, $target, pHeight, pWidth, promiseForSpotInViewport, scrollTop, spot, spotPad, tHeight, tMidPtCoords, tOffsetX, tOffsetY, tRadius, tWidth;
spotPad = 10;
$target = $(data.selector).eq(0);
$page = $($document);
$mainContentWrapper = $(".main-app__header-and-content").eq(0);
tWidth = $target.outerWidth();
tHeight = $target.outerHeight();
tOffsetX = $target.offset().left;
tOffsetY = $target.offset().top;
scrollTop = $mainContentWrapper.scrollTop();
tMidPtCoords = {
left: tOffsetX + (tWidth / 2),
top: tOffsetY + (tHeight / 2)
};
pWidth = $page.width();
pHeight = $page.height();
tRadius = Math.sqrt(Math.pow(tWidth / 2, 2) + Math.pow(tHeight / 2, 2));
spot = {};
spot.radius = tRadius + spotPad;
spot.dim = spot.radius * 2;
spot.x = tMidPtCoords.left - spot.radius;
spot.y = tMidPtCoords.top - spot.radius;
if (data.adjustments) {
spot = scope.calculateSpotAdjustments(data.adjustments, tMidPtCoords, spot);
}
promiseForSpotInViewport = scope.asyncEnsureSpotInViewport(scrollTop, pHeight, spot, $mainContentWrapper);
return promiseForSpotInViewport.then(function(adjustedValues) {
return $timeout(function() {
var $boxBottom, $boxCenter, $boxLeft, $boxMiddleWrapper, $boxRight, $boxTop, boxBottomHeight, boxCenterHeight, boxLeftWidth, boxMiddleWrapperWidth, boxRightWidth, boxTopHeight, showContent;
if (adjustedValues.y !== void 0) {
spot.y = adjustedValues.y;
}
scope.showSpotlight = true;
showContent = function() {
scope.showTutorialBox = true;
if (data.onHighlight) {
return data.onHighlight();
}
};
$timeout(showContent, 700);
scope.tutorialTarget = {
spot: spot,
title: data.title,
content: data.content
};
if (data.hideBack) {
scope.tutorialTarget.hideBack = true;
}
boxLeftWidth = spot.x;
boxMiddleWrapperWidth = spot.dim;
boxTopHeight = spot.y;
boxCenterHeight = spot.dim;
boxBottomHeight = pHeight - boxCenterHeight - boxTopHeight;
boxRightWidth = pWidth - boxMiddleWrapperWidth - boxLeftWidth;
$boxLeft = elem.find(".it__box--left");
$boxMiddleWrapper = elem.find(".it__box-middle-wrapper");
$boxTop = elem.find(".it__box--top");
$boxCenter = elem.find(".it__box--center");
$boxBottom = elem.find(".it__box--bottom");
$boxRight = elem.find(".it__box--right");
$boxLeft.css("width", boxLeftWidth + "px");
$boxMiddleWrapper.css("width", boxMiddleWrapperWidth + "px");
$boxTop.css("height", boxTopHeight + "px");
$boxBottom.css("height", boxBottomHeight + "px");
$boxCenter.css("height", boxCenterHeight + "px");
return $boxRight.css("width", boxRightWidth + "px");
});
});
};
}
};
});