<commit_before>/**
 * Copyright © 2019 Aga Khan Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 **/

import SnapKit
import UIKit

class OnboardingViewController: ViewController {
  enum State {
    case welcome(Welcome)
    case onboarding(Onboarding)

    var totalPages: Int {
      switch self {
      case .welcome: return Welcome.allCases.count
      case .onboarding: return Onboarding.allCases.count
      }
    }

    var currentIndex: Int {
      switch self {
      case .welcome(let value): return value.rawValue
      case .onboarding(let value): return value.rawValue
      }
    }
  }

  enum Welcome: Int, CaseIterable {
    case initial = 0
  }

  enum Onboarding: Int, CaseIterable {
    case create = 0
    case complete
    case track
  }

  var state: State = .welcome(.initial)

  private let continueButton = Button(style: .primary)
  private let skipButton = Button(style: .secondary)
  private let pageViewController = UIPageViewController(
    transitionStyle: .scroll,
    navigationOrientation: .horizontal,
    options: nil)

  // PageController Related
  private lazy var pageControl: UIPageControl? = pageViewController.pageControl
  private var viewControllers: [UIViewController] = []
  private let welcomePage = OnboardingPageViewController(context: OnboardingPageViewController.PageContext(
    title: Strings.Welcome.title,
    asset: Assets.onboardingLoginPeople,
    tagLine: Strings.Welcome.thanks))
  private let createPage = OnboardingPageViewController(context: OnboardingPageViewController.PageContext(
    title: Strings.Onboarding.createTeam,
    asset: Assets.onboardingCreateTeam))
  private let completePage = OnboardingPageViewController(context: OnboardingPageViewController.PageContext(
    title: Strings.Onboarding.journey,
    asset: Assets.onboardingJourney))
  private let trackPage = OnboardingPageViewController(context: OnboardingPageViewController.PageContext(
    title: Strings.Onboarding.dashboard,
    asset: Assets.onboardingDashboard))

  override func configureView() {
    super.configureView()

    continueButton.title = Strings.Onboarding.continue
    continueButton.addTarget(self, action: #selector(continueTapped), for: .touchUpInside)
    skipButton.title = Strings.Welcome.skip
    skipButton.addTarget(self, action: #selector(skipTapped), for: .touchUpInside)
    pageViewController.dataSource = self
    pageViewController.delegate = self
    pageControl?.hidesForSinglePage = true
    pageControl?.currentPageIndicatorTintColor = Style.Colors.FoundationGreen
    pageControl?.pageIndicatorTintColor = Style.Colors.grey
    updateForState()

    let stackView = UIStackView()
    stackView.axis = .vertical
    stackView.spacing = Style.Padding.p8
    stackView.distribution = .fillEqually
    stackView.addArrangedSubviews(continueButton, skipButton)
    view.addSubview(stackView) {
      $0.leading.trailing.equalToSuperview().inset(Style.Padding.p32)
      $0.bottom.equalTo(view.safeAreaLayoutGuide)
    }

    pageViewController.willMove(toParent: self)
    view.addSubview(pageViewController.view) {
      $0.leading.trailing.equalToSuperview()
      $0.top.equalTo(view.safeAreaLayoutGuide)
      $0.bottom.equalTo(stackView.snp.top)
    }
    pageViewController.didMove(toParent: self)
  }

  private func currentViewController(for state: State) -> UIViewController {
    switch state {
    case .welcome(let welcome):
      switch welcome {
      case .initial: return welcomePage
      }
    case .onboarding(let onboarding):
      switch onboarding {
      case .complete: return completePage
      case .create: return createPage
      case .track: return trackPage
      }
    }
  }

  private func state(for viewController: UIViewController?) -> State? {<commit_msg>add inset on bottom<commit_after>/**
 * Copyright © 2019 Aga Khan Foundation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 **/

import SnapKit
import UIKit

class OnboardingViewController: ViewController {
  enum State {
    case welcome(Welcome)
    case onboarding(Onboarding)

    var totalPages: Int {
      switch self {
      case .welcome: return Welcome.allCases.count
      case .onboarding: return Onboarding.allCases.count
      }
    }

    var currentIndex: Int {
      switch self {
      case .welcome(let value): return value.rawValue
      case .onboarding(let value): return value.rawValue
      }
    }
  }

  enum Welcome: Int, CaseIterable {
    case initial = 0
  }

  enum Onboarding: Int, CaseIterable {
    case create = 0
    case complete
    case track
  }

  var state: State = .welcome(.initial)

  private let continueButton = Button(style: .primary)
  private let skipButton = Button(style: .secondary)
  private let pageViewController = UIPageViewController(
    transitionStyle: .scroll,
    navigationOrientation: .horizontal,
    options: nil)

  // PageController Related
  private lazy var pageControl: UIPageControl? = pageViewController.pageControl
  private var viewControllers: [UIViewController] = []
  private let welcomePage = OnboardingPageViewController(context: OnboardingPageViewController.PageContext(
    title: Strings.Welcome.title,
    asset: Assets.onboardingLoginPeople,
    tagLine: Strings.Welcome.thanks))
  private let createPage = OnboardingPageViewController(context: OnboardingPageViewController.PageContext(
    title: Strings.Onboarding.createTeam,
    asset: Assets.onboardingCreateTeam))
  private let completePage = OnboardingPageViewController(context: OnboardingPageViewController.PageContext(
    title: Strings.Onboarding.journey,
    asset: Assets.onboardingJourney))
  private let trackPage = OnboardingPageViewController(context: OnboardingPageViewController.PageContext(
    title: Strings.Onboarding.dashboard,
    asset: Assets.onboardingDashboard))

  override func configureView() {
    super.configureView()

    continueButton.title = Strings.Onboarding.continue
    continueButton.addTarget(self, action: #selector(continueTapped), for: .touchUpInside)
    skipButton.title = Strings.Welcome.skip
    skipButton.addTarget(self, action: #selector(skipTapped), for: .touchUpInside)
    pageViewController.dataSource = self
    pageViewController.delegate = self
    pageControl?.hidesForSinglePage = true
    pageControl?.currentPageIndicatorTintColor = Style.Colors.FoundationGreen
    pageControl?.pageIndicatorTintColor = Style.Colors.grey
    updateForState()

    let stackView = UIStackView()
    stackView.axis = .vertical
    stackView.spacing = Style.Padding.p8
    stackView.distribution = .fillEqually
    stackView.addArrangedSubviews(continueButton, skipButton)
    view.addSubview(stackView) {
      $0.leading.trailing.equalToSuperview().inset(Style.Padding.p32)
      $0.bottom.equalTo(view.safeAreaLayoutGuide).inset(Style.Padding.p16)
    }

    pageViewController.willMove(toParent: self)
    view.addSubview(pageViewController.view) {
      $0.leading.trailing.equalToSuperview()
      $0.top.equalTo(view.safeAreaLayoutGuide)
      $0.bottom.equalTo(stackView.snp.top)
    }
    pageViewController.didMove(toParent: self)
  }

  private func currentViewController(for state: State) -> UIViewController {
    switch state {
    case .welcome(let welcome):
      switch welcome {
      case .initial: return welcomePage
      }
    case .onboarding(let onboarding):
      switch onboarding {
      case .complete: return completePage
      case .create: return createPage
      case .track: return trackPage
      }
    }
  }

  private func state(for viewController: UIViewController?) -> State? {
{'fraction_non_alphanumeric': 0.07402031930333818, 'fraction_numerical': 0.0034833091436865023, 'mean_word_length': 3.9289461134954697, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5523636', 'n_tokens_mistral': 2936, 'n_tokens_neox': 2686, 'n_words': 877}