<commit_before>//
//  GameViewController.swift
//  CodeCombat
//
//  Created by <NAME> on 10/24/14.
//  Copyright (c) 2014 CodeCombat. All rights reserved.
//

import Foundation
import WebKit
import StoreKit

var autoLoggedIn: Bool = false  // Wish class variables were supported.

class GameViewController: UIViewController, UIActionSheetDelegate {
  var webManager = WebManager.sharedInstance
  var webView: WKWebView = WebManager.sharedInstance.webView!
  var playViewController: PlayViewController?
  var playLevelRoutePrefix = "/play/level/"
  var memoryWarningView:MemoryWarningViewController!
  var memoryWarningCountdownTimer:NSTimer!
  var memoryWarningCountdownCounts = 0
  let memoryWarningCountdownDuration = 5
  var memoryWarningsReceived = 0
  var memoryAlertController:UIAlertController!
  var productBeingPurchased:SKProduct!
  
  override func viewDidLoad() {
    super.viewDidLoad()
    webView = WebManager.sharedInstance.webView!
    view.addSubview(webView)
    view.sendSubviewToBack(webView)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("listenToNotifications"), name: "webViewDidFinishNavigation", object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("onWebsiteNotReachable"), name: "websiteNotReachable", object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("onWebsiteReachable"), name: "websiteReachable", object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("onLoginFailure"), name: "loginFailure", object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("onWebViewReloadedFromCrash"), name: "webViewReloadedFromCrash", object: nil)
  }
  
  func listenToNotifications() {
    delay(1, {
      self.webManager.subscribe(self, channel: "router:navigated", selector: Selector("onNavigated:"))
      self.webManager.subscribe(self, channel: "level:loading-view-unveiled", selector: Selector("onLevelStarted:"))
      self.webManager.subscribe(self, channel: "auth:logging-out", selector: Selector("onLogout"))
      self.webManager.subscribe(self, channel: "buy-gems-modal:update-products", selector: Selector("onBuyGemsModalUpdateProducts"))
      self.webManager.subscribe(self, channel: "buy-gems-modal:purchase-initiated", selector: Selector("onBuyGemsModalPurchaseInitiated:"))
      self.webManager.subscribe(self, channel: "auth:signed-up", selector: Selector("onSignedUp"))
      //webManager.subscribe(self, channel: "supermodel:load-progress-changed", selector: Selector("onProgressUpdate:"))
      NSNotificationCenter.defaultCenter().removeObserver(self, name: "webViewDidFinishNavigation", object: nil)
    })
  }
  
  func onSignedUp() {
    println("Signed up!")
    webManager.clearCredentials()
  }
  
  func onBuyGemsModalUpdateProducts() {
    if CodeCombatIAPHelper.sharedInstance.productsDict.count != 0 {
      sendIPadProductsToWebView()
    } else {
      CodeCombatIAPHelper.sharedInstance.requestProductsWithCompletionHandler({ (success, products) -> Void in
        if success {
          self.onBuyGemsModalUpdateProducts()
        } else {
          println("Failed to get list of products")
        }
      })
    }
    
  }
  
  func onBuyGemsModalPurchaseInitiated(note:NSNotification) {
    let productID = note.userInfo!["productID"] as String
    let desiredProduct = CodeCombatIAPHelper.sharedInstance.productsDict[productID]
    println("WANTS TO BUY PRODUCT \(productID)")
    if desiredProduct != nil {
      productBeingPurchased = desiredProduct!
      CodeCombatIAPHelper.sharedInstance.buyProduct(desiredProduct!)
      NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("onProductPurchased"), name: "productPurchased", object: nil)
    }
  }
  
  func onProductPurchased() {
    NSNotificationCenter.defaultCenter().removeObserver(self, name: "productPurchased", object: nil)
    productBeingPurchased = nil
    webManager.publish("ipad:iap-complete", event: [:])
    webManager.webView!.reload()
  }
  
  func sendIPadProductsToWebView() {
    var productsToSend:[[String:AnyObject]] = []
    for (productID, product) in CodeCombatIAPHelper.sharedInstance.productsDict {
      var productDict:[String:AnyObject] = [:]
      productDict["price"] = CodeCombatIAPHelper.sharedInstance.localizedPriceForProduct(product)
      productDict["id"] = product.productIdentifier
      productsToSend.append(productDict)
    }
    let productsObject = ["products":productsToSend]
    webManager.publish("ipad:products", event: productsObject)
  }
  
  //This listens for when the NSURLConnection login fails (aka password has changed, etc.)
  func onLoginFailure() {
    println("Login failed!")
    if !currentCredentialIsPseudoanonymous() {
      WebManager.sharedInstance.clearCredentials()
    }
    
    dismissViewControllerAnimated(true, completion:nil)
  }
  
  func currentCredentialIsPseudoanonymous() -> Bool {
    let credentials = webManager.getCredentials()
    if !credentials.isEmpty && credentials.first!.user != nil && countElements(credentials.first!.user!) == 36 && NSUserDefaults.standardUserDefaults().boolForKey("pseudoanonymousUserCreated") {
      let uuid = NSUUID(UUIDString: credentials.first!.user!)
      return uuid != nil
    }
    return false
  }
  
  func onWebsiteNotReachable() {
    println("Game view controller showing not reachable alert")
    if memoryAlertController == nil {
      memoryAlertController = UIAlertController(title: "Internet connection problem", message: "We can't reach the CodeCombat server. Please check your connection and try again.", preferredStyle: UIAlertControllerStyle.Alert)
      memoryAlertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: { success in
        self.memoryAlertController.dismissViewControllerAnimated(true, completion: nil)
        self.memoryAlertController = nil
      }))
      presentViewController(memoryAlertController, animated: true, completion: nil)
    }
  }
  
  func onWebsiteReachable() {
    if memoryAlertController != nil {
      memoryAlertController.dismissViewControllerAnimated(true, completion: {
        self.memoryAlertController = nil
      })
    }
  }
  
  override func didReceiveMemoryWarning() {
    memoryWarningsReceived++
    if memoryWarningsReceived % 3 == 0 {
      showMemoryWarningDialogue()
    }
    println("----------------- Received Memory Warning --------------")
    NSURLCache.sharedURLCache().removeAllCachedResponses()
    webManager.publish("ipad:memory-warning", event: [:])
    super.didReceiveMemoryWarning()
  }
  
  private func showMemoryWarningDialogue() {
    if memoryWarningView != nil {
      memoryWarningCountdownCounts = memoryWarningCountdownDuration
      return
    }
    memoryWarningView = MemoryWarningViewController(nibName: "MemoryWarningViewController", bundle:nil)
    addChildViewController(memoryWarningView)
    var warningViewFrame = memoryWarningView.view.frame
    warningViewFrame.origin.y = 50
    warningViewFrame.origin.x = (view.bounds.width - warningViewFrame.width)/2
    memoryWarningView.view.frame = warningViewFrame
    memoryWarningView.view.layer.cornerRadius = 5
    memoryWarningView.view.layer.masksToBounds = true
    memoryWarningView.view.layer.borderColor = UIColor.blackColor().CGColor
    memoryWarningView.view.layer.borderWidth = 2
    view.addSubview(memoryWarningView.view)
    memoryWarningCountdownCounts = memoryWarningCountdownDuration
    memoryWarningCountdownTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("countDownMemoryWarning"), userInfo: nil, repeats: true)
  }
  
  func countDownMemoryWarning() {
    memoryWarningCountdownCounts--
    println("Counting down!")
    if memoryWarningCountdownCounts == 0 {
      memoryWarningCountdownTimer.invalidate()
      UIView.animateWithDuration(2, animations: {
        self.memoryWarningView.view.alpha = 0
        }, completion: { success in
          self.memoryWarningView.view.removeFromSuperview()
          self.memoryWarningView.removeFromParentViewController()
          self.memoryWarningCountdownCounts = self.memoryWarningCountdownDuration
          self.memoryWarningView = nil
      })
    }
  }
  
  func onWebViewReloadedFromCrash() {
    println("GameViewController going to reload its webview \(webManager.webView?)")
    webView = webManager.webView!
    if webView.superview == view {
      view.sendSubviewToBack(webView)
    }
    displayWebViewCrashedAlert()
  }
  
  func displayWebViewCrashedAlert() {
    let alertController = UIAlertController(title: "The web view ran out of memory!", message: "The web view ran out of memory and crashed! Don't worry, just hang on and wait for the level to reload.", preferredStyle: .Alert)
    let OKAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
    alertController.addAction(OKAction)
    self.presentViewController(alertController, animated: true, completion: nil)
  }
  
  deinit {
    WebManager.sharedInstance.unsubscribe(self)
  }
  
  func onLogout() {<commit_msg>Changed web view to graphics layer<commit_after>//
//  GameViewController.swift
//  CodeCombat
//
//  Created by <NAME> on 10/24/14.
//  Copyright (c) 2014 CodeCombat. All rights reserved.
//

import Foundation
import WebKit
import StoreKit

var autoLoggedIn: Bool = false  // Wish class variables were supported.

class GameViewController: UIViewController, UIActionSheetDelegate {
  var webManager = WebManager.sharedInstance
  var webView: WKWebView = WebManager.sharedInstance.webView!
  var playViewController: PlayViewController?
  var playLevelRoutePrefix = "/play/level/"
  var memoryWarningView:MemoryWarningViewController!
  var memoryWarningCountdownTimer:NSTimer!
  var memoryWarningCountdownCounts = 0
  let memoryWarningCountdownDuration = 5
  var memoryWarningsReceived = 0
  var memoryAlertController:UIAlertController!
  var productBeingPurchased:SKProduct!
  
  override func viewDidLoad() {
    super.viewDidLoad()
    webView = WebManager.sharedInstance.webView!
    view.addSubview(webView)
    view.sendSubviewToBack(webView)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("listenToNotifications"), name: "webViewDidFinishNavigation", object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("onWebsiteNotReachable"), name: "websiteNotReachable", object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("onWebsiteReachable"), name: "websiteReachable", object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("onLoginFailure"), name: "loginFailure", object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("onWebViewReloadedFromCrash"), name: "webViewReloadedFromCrash", object: nil)
  }
  
  func listenToNotifications() {
    delay(1, {
      self.webManager.subscribe(self, channel: "router:navigated", selector: Selector("onNavigated:"))
      self.webManager.subscribe(self, channel: "level:loading-view-unveiled", selector: Selector("onLevelStarted:"))
      self.webManager.subscribe(self, channel: "auth:logging-out", selector: Selector("onLogout"))
      self.webManager.subscribe(self, channel: "buy-gems-modal:update-products", selector: Selector("onBuyGemsModalUpdateProducts"))
      self.webManager.subscribe(self, channel: "buy-gems-modal:purchase-initiated", selector: Selector("onBuyGemsModalPurchaseInitiated:"))
      self.webManager.subscribe(self, channel: "auth:signed-up", selector: Selector("onSignedUp"))
      //webManager.subscribe(self, channel: "supermodel:load-progress-changed", selector: Selector("onProgressUpdate:"))
      NSNotificationCenter.defaultCenter().removeObserver(self, name: "webViewDidFinishNavigation", object: nil)
    })
  }
  
  func onSignedUp() {
    println("Signed up!")
    webManager.clearCredentials()
  }
  
  func onBuyGemsModalUpdateProducts() {
    if CodeCombatIAPHelper.sharedInstance.productsDict.count != 0 {
      sendIPadProductsToWebView()
    } else {
      CodeCombatIAPHelper.sharedInstance.requestProductsWithCompletionHandler({ (success, products) -> Void in
        if success {
          self.onBuyGemsModalUpdateProducts()
        } else {
          println("Failed to get list of products")
        }
      })
    }
    
  }
  
  func onBuyGemsModalPurchaseInitiated(note:NSNotification) {
    let productID = note.userInfo!["productID"] as String
    let desiredProduct = CodeCombatIAPHelper.sharedInstance.productsDict[productID]
    println("WANTS TO BUY PRODUCT \(productID)")
    if desiredProduct != nil {
      productBeingPurchased = desiredProduct!
      CodeCombatIAPHelper.sharedInstance.buyProduct(desiredProduct!)
      NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("onProductPurchased"), name: "productPurchased", object: nil)
    }
  }
  
  func onProductPurchased() {
    NSNotificationCenter.defaultCenter().removeObserver(self, name: "productPurchased", object: nil)
    productBeingPurchased = nil
    webManager.publish("ipad:iap-complete", event: [:])
    webManager.webView!.reload()
  }
  
  func sendIPadProductsToWebView() {
    var productsToSend:[[String:AnyObject]] = []
    for (productID, product) in CodeCombatIAPHelper.sharedInstance.productsDict {
      var productDict:[String:AnyObject] = [:]
      productDict["price"] = CodeCombatIAPHelper.sharedInstance.localizedPriceForProduct(product)
      productDict["id"] = product.productIdentifier
      productsToSend.append(productDict)
    }
    let productsObject = ["products":productsToSend]
    webManager.publish("ipad:products", event: productsObject)
  }
  
  //This listens for when the NSURLConnection login fails (aka password has changed, etc.)
  func onLoginFailure() {
    println("Login failed!")
    if !currentCredentialIsPseudoanonymous() {
      WebManager.sharedInstance.clearCredentials()
    }
    
    dismissViewControllerAnimated(true, completion:nil)
  }
  
  func currentCredentialIsPseudoanonymous() -> Bool {
    let credentials = webManager.getCredentials()
    if !credentials.isEmpty && credentials.first!.user != nil && countElements(credentials.first!.user!) == 36 && NSUserDefaults.standardUserDefaults().boolForKey("pseudoanonymousUserCreated") {
      let uuid = NSUUID(UUIDString: credentials.first!.user!)
      return uuid != nil
    }
    return false
  }
  
  func onWebsiteNotReachable() {
    println("Game view controller showing not reachable alert")
    if memoryAlertController == nil {
      memoryAlertController = UIAlertController(title: "Internet connection problem", message: "We can't reach the CodeCombat server. Please check your connection and try again.", preferredStyle: UIAlertControllerStyle.Alert)
      memoryAlertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: { success in
        self.memoryAlertController.dismissViewControllerAnimated(true, completion: nil)
        self.memoryAlertController = nil
      }))
      presentViewController(memoryAlertController, animated: true, completion: nil)
    }
  }
  
  func onWebsiteReachable() {
    if memoryAlertController != nil {
      memoryAlertController.dismissViewControllerAnimated(true, completion: {
        self.memoryAlertController = nil
      })
    }
  }
  
  override func didReceiveMemoryWarning() {
    memoryWarningsReceived++
    if memoryWarningsReceived % 3 == 0 {
      showMemoryWarningDialogue()
    }
    println("----------------- Received Memory Warning --------------")
    NSURLCache.sharedURLCache().removeAllCachedResponses()
    webManager.publish("ipad:memory-warning", event: [:])
    super.didReceiveMemoryWarning()
  }
  
  private func showMemoryWarningDialogue() {
    if memoryWarningView != nil {
      memoryWarningCountdownCounts = memoryWarningCountdownDuration
      return
    }
    memoryWarningView = MemoryWarningViewController(nibName: "MemoryWarningViewController", bundle:nil)
    addChildViewController(memoryWarningView)
    var warningViewFrame = memoryWarningView.view.frame
    warningViewFrame.origin.y = 50
    warningViewFrame.origin.x = (view.bounds.width - warningViewFrame.width)/2
    memoryWarningView.view.frame = warningViewFrame
    memoryWarningView.view.layer.cornerRadius = 5
    memoryWarningView.view.layer.masksToBounds = true
    memoryWarningView.view.layer.borderColor = UIColor.blackColor().CGColor
    memoryWarningView.view.layer.borderWidth = 2
    view.addSubview(memoryWarningView.view)
    memoryWarningCountdownCounts = memoryWarningCountdownDuration
    memoryWarningCountdownTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("countDownMemoryWarning"), userInfo: nil, repeats: true)
  }
  
  func countDownMemoryWarning() {
    memoryWarningCountdownCounts--
    println("Counting down!")
    if memoryWarningCountdownCounts == 0 {
      memoryWarningCountdownTimer.invalidate()
      UIView.animateWithDuration(2, animations: {
        self.memoryWarningView.view.alpha = 0
        }, completion: { success in
          self.memoryWarningView.view.removeFromSuperview()
          self.memoryWarningView.removeFromParentViewController()
          self.memoryWarningCountdownCounts = self.memoryWarningCountdownDuration
          self.memoryWarningView = nil
      })
    }
  }
  
  func onWebViewReloadedFromCrash() {
    println("GameViewController going to reload its webview \(webManager.webView?)")
    webView = webManager.webView!
    if webView.superview == view {
      view.sendSubviewToBack(webView)
    }
    displayWebViewCrashedAlert()
  }
  
  func displayWebViewCrashedAlert() {
    let alertController = UIAlertController(title: "The graphics layer ran out of memory!", message: "The graphics layer ran out of memory and crashed! Don't worry, just hang on and wait for the level to reload.", preferredStyle: .Alert)
    let OKAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
    alertController.addAction(OKAction)
    self.presentViewController(alertController, animated: true, completion: nil)
  }
  
  deinit {
    WebManager.sharedInstance.unsubscribe(self)
  }
  
  func onLogout() {
{'fraction_non_alphanumeric': 0.10187257738712671, 'fraction_numerical': 0.0030572692034721845, 'mean_word_length': 4.471326164874552, 'pattern_counts': {'":': 2, '<': 5, '<?xml version=': 0, '>': 9, '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': '1061941', 'n_tokens_mistral': 5218, 'n_tokens_neox': 5041, 'n_words': 997}