// // TakeQuizViewController.swift // Learn Genie // // Created by Suraj Kumar Mandal on 15/09/21. // import UIKit import Alamofire class TakeQuizViewController: UIViewController { @IBOutlet var quesHeadLabel: UILabel! @IBOutlet var timerLabel: UILabel! @IBOutlet var questionLabel: UILabel! @IBOutlet var nextButton: UIButton! @IBOutlet var previousButton: UIButton! @IBOutlet var cancelButton: UIButton! @IBOutlet var minuteSecondLabel: UILabel! @IBOutlet var choiceCollectionView: UICollectionView! @IBOutlet var choiceCollectionViewHeight: NSLayoutConstraint! //Result submit pop up view outlets @IBOutlet var submitPopupView: UIView! @IBOutlet var resultImageView: UIImageView! @IBOutlet var resultHeadingLabel: UILabel! @IBOutlet var resultSubHeadingLabel: UILabel! @IBOutlet var tryAgainButton: UIButton! @IBOutlet var popUpNextButton: UIButton! @IBOutlet var viewAnswerButton: UIButton! var timer = Timer() var secondsLeft: Int = 300 var quesIndex = 0 var selectedAnswer = [SelectedAnswerModel]() let studentId = UserDefaultsConstant.getIntValueFromUserDefults(for: Constant.studentId) as! Int var topicId = Int() var quesBankId = Int() var quesId = Int() var selectedChoiceId = Int() var answerChoiceId = Int() var choiceArray = [Int]() var selectedButtonIndexPath: IndexPath? //Not changing values in quiz process var levelId = Int() var runs = Int() var wickets = Int() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. choiceCollectionView.delegate = self choiceCollectionView.dataSource = self ApiManager.generateCookie() } override func viewWillAppear(_ animated: Bool) { self.timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.runScheduledTask), userInfo: nil, repeats: true) setupUI() selectedAnswer.removeAll() } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() let height = choiceCollectionView.collectionViewLayout.collectionViewContentSize.height choiceCollectionViewHeight.constant = height self.view.layoutIfNeeded() } func setupUI() { getQuesBankId() submitPopupView.isHidden = true self.quesHeadLabel.text = "\(Helper.translateText(inputText: "Question")) \(quesIndex+1)" if quesIndex == 4 { nextButton.setTitle(Helper.translateText(inputText: "SUBMIT"), for: .normal) } else { nextButton.setTitle(Helper.translateText(inputText: "Next"), for: .normal) } previousButton.setTitle(Helper.translateText(inputText: "Previous"), for: .normal) cancelButton.setTitle(Helper.translateText(inputText: "CANCEL"), for: .normal) nextButton.setTitle(Helper.translateText(inputText: "Next"), for: .normal) tryAgainButton.setTitle(Helper.translateText(inputText: "TRY AGAIN"), for: .normal) popUpNextButton.setTitle(Helper.translateText(inputText: "Next"), for: .normal) viewAnswerButton.setTitle(Helper.translateText(inputText: "View Answer"), for: .normal) minuteSecondLabel.text = "\(Helper.translateText(inputText: "Minutes")) : \(Helper.translateText(inputText: "Seconds"))" } @objc func runScheduledTask(_ runningTimer: Timer) { var minute: Int var second: Int secondsLeft -= 1 if secondsLeft == 0 || secondsLeft < 0 { timerLabel.text = "00 : 00" timer.invalidate() getResult() saveScoreBoard() } else { minute = (secondsLeft % 3600) / 60 second = (secondsLeft % 3600) % 60 timerLabel.text = "\(String(format: "%02d", minute)) : \(String(format: "%02d", second))" print() } } func getQuesBankId() { let topicData = DBManager.sharedInstance.database.objects(TopicModel.self) for item in topicData { if self.topicId == item.id { self.levelId = item.levelId self.quesBankId = item.questionBankId self.choiceArray.removeAll() let quesBankData = DBManager.sharedInstance.database.objects(QuestionBankModel.self) for item in quesBankData { if self.quesBankId == item.id { print(item.questions[quesIndex]) let quesData = DBManager.sharedInstance.database.objects(QuestionModel.self) for data in quesData { if data.id == item.questions[quesIndex].id { print("Current Question: \(data.content)") self.quesId = data.id self.answerChoiceId = data.answerId self.questionLabel.text = Helper.translateText(inputText: data.content) for choice in data.choices { let id = choice.id self.choiceArray.append(id) } } } } } } } print("Current choices: \(choiceArray)") choiceCollectionView.reloadData() } func getChoice(id:Int) -> String { let choiceData = DBManager.sharedInstance.database.objects(ChoiceModel.self) var choiceString = "" for choice in choiceData { if id == choice.id { choiceString = choice.content } } return choiceString } func saveSelectedChoice() { if let row = self.selectedAnswer.firstIndex(where: {$0.quesId == self.quesId}) { print("Before update: \(selectedAnswer[row])") selectedAnswer[row].choiceId = self.selectedChoiceId print("After update: \(selectedAnswer[row])") } else { let answer = SelectedAnswerModel(quesId: quesId, choiceId: selectedChoiceId, answerId: answerChoiceId) selectedAnswer.append(answer) } for item in selectedAnswer { print("Saved QuesId: \(item.quesId), Saved ChoiceId: \(item.choiceId), Saved Answer: \(item.answerId)") } } func getSelectedChoice() { if let row = self.selectedAnswer.firstIndex(where: {$0.quesId == self.quesId}) { selectedAnswer[row].choiceId = self.selectedChoiceId } } @objc func selectChoice(sender: UIButton) { let buttonPosition:CGPoint = sender.convert(CGPoint.zero, to:self.choiceCollectionView) let indexPath = self.choiceCollectionView.indexPathForItem(at: buttonPosition) if indexPath != selectedButtonIndexPath { selectedButtonIndexPath = indexPath } else { // If same button selected, deselect? Unless you want a different behavior selectedButtonIndexPath = nil } choiceCollectionView.reloadData() } func getCorrectAnswerNumber() -> Int { var score = 0 for answer in selectedAnswer { if answer.choiceId == answer.answerId { score += 1 } } return score } func getResult() { switch getCorrectAnswerNumber() { case 0, 1: resultImageView.image = UIImage(named: "i_run_out") resultHeadingLabel.text = Helper.translateText(inputText: "Oh No You are Out Better luck next time") resultSubHeadingLabel.text = "\(Helper.translateText(inputText: "You have got")) \(getCorrectAnswerNumber())/5 \(Helper.translateText(inputText: "questions right"))" runs = 0 wickets = 1 return case 2: resultImageView.image = UIImage(named: "i_run_two") resultHeadingLabel.text = Helper.translateText(inputText: "It\'s a two Try Again") resultSubHeadingLabel.text = "\(Helper.translateText(inputText: "You have got")) \(getCorrectAnswerNumber())/5 \(Helper.translateText(inputText: "questions right"))" runs = 0 wickets = 0 return case 3: resultImageView.image = UIImage(named: "i_run_three") resultHeadingLabel.text = Helper.translateText(inputText: "It\'s a three Nice Hit") resultSubHeadingLabel.text = "\(Helper.translateText(inputText: "You have got")) \(getCorrectAnswerNumber())/5 \(Helper.translateText(inputText: "questions right"))" runs = 3 wickets = 0 return case 4: resultImageView.image = UIImage(named: "i_run_four") resultHeadingLabel.text = Helper.translateText(inputText: "It\'s a four What a tremendous hit") resultSubHeadingLabel.text = "\(Helper.translateText(inputText: "You have got")) \(getCorrectAnswerNumber())/5 \(Helper.translateText(inputText: "questions right"))" runs = 4 wickets = 0 return case 5: resultImageView.image = UIImage(named: "i_run_six") resultHeadingLabel.text = Helper.translateText(inputText: "It\'s a six What a tremendous hit") resultSubHeadingLabel.text = "\(Helper.translateText(inputText: "You have got")) \(getCorrectAnswerNumber())/5 \(Helper.translateText(inputText: "questions right"))" runs = 6 wickets = 0 return default: return } } func saveScoreBoard() { if Reachability.isConnectedToNetwork() { let saveScore = [SaveScoreBoard]() var noOfAttempts = 0 for quiz in saveScore { if quiz.topicId == self.topicId { noOfAttempts += 1 } else { noOfAttempts = 1 } } saveScoreboard(levelId: self.levelId, topicId: self.topicId, runs: self.runs, wickets: self.wickets, noOfAttempts: noOfAttempts) } else { var saveScore = [SaveScoreBoard]() let itemId = saveScore.count + 1 var noOfAttempts = 0 for quiz in saveScore { if quiz.topicId == self.topicId { noOfAttempts += 1 } else { noOfAttempts = 1 } } let newSaveScoreModel = SaveScoreBoard(id: itemId, levelId: levelId, topicId: topicId, runs: runs, wickets: wickets, noOfAttempts: noOfAttempts, student: studentId, synced: false) saveScore.append(newSaveScoreModel) DBManager.sharedInstance.addData(objs: saveScore) let quizTakenData = DBManager.sharedInstance.database.objects(SaveScoreBoard.self) print(quizTakenData.count) } } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. } */ @IBAction func quizButtonAction(_ sender: UIButton) { switch sender.tag { case 0: if quesIndex > 0 { quesIndex -= 1 setupUI() //getSelectedChoice() } break case 1: if quesIndex == 4 { saveSelectedChoice() Alert.showAlertWithAction(vc: self, title: Helper.translateText(inputText: "Are you sure, you want to submit the quiz?"), message: "\(Helper.translateText(inputText: "You have completed")) \(selectedAnswer.count) \(Helper.translateText(inputText: "out of")) 5 \(Helper.translateText(inputText: "questions"))", alertStyle: .alert, actionTitles: [Helper.translateText(inputText: "CANCEL"), Helper.translateText(inputText: "YES")], actionStyles: [.cancel, .default], actions: [{_ in print("cancel click") }, {[self]_ in print("yes click") timer.invalidate() getResult() saveScoreBoard() }]) } else { if quesIndex < 4 { saveSelectedChoice() selectedButtonIndexPath = nil quesIndex += 1 setupUI() } } break case 2: Alert.showAlertWithAction(vc: self, title: Helper.translateText(inputText: "Are you sure you want to exit the quiz?"), message: "", alertStyle: .alert, actionTitles: [Helper.translateText(inputText: "CANCEL"), Helper.translateText(inputText: "YES")], actionStyles: [.cancel, .default], actions: [{_ in print("cancel click") }, { [self]_ in print("yes click") timer.invalidate() self.navigationController?.popViewController(animated: true) }]) break default: break } } @IBAction func resultPopupCloseAction(_ sender: Any) { submitPopupView.isHidden = true } @IBAction func resultPopupButtonAction(_ sender: UIButton) { switch sender.tag { case 0: submitPopupView.isHidden = true self.navigationController?.popViewController(animated: true) case 1: submitPopupView.isHidden = true self.navigationController?.popViewController(animated: true) case 2: //submitPopupView.isHidden = true DispatchQueue.main.async { let viewAnswerVC = self.storyboard?.instantiateViewController(withIdentifier: "ViewAnswerViewController") as! ViewAnswerViewController viewAnswerVC.selectedAnswer.removeAll() viewAnswerVC.selectedAnswer = self.selectedAnswer self.navigationController?.pushViewController(viewAnswerVC, animated: true) } default: return } } } extension TakeQuizViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return choiceArray.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { guard let cell: ChoiceCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "ChoiceCollectionViewCell", for: indexPath) as? ChoiceCollectionViewCell else { return UICollectionViewCell() } cell.choiceLabel.text = Helper.translateText(inputText: getChoice(id: choiceArray[indexPath.row])) cell.radioButton.tag = indexPath.row cell.radioButton.addTarget(self, action: #selector(selectChoice(sender:)), for: .touchUpInside) if let row = self.selectedAnswer.firstIndex(where: {$0.quesId == self.quesId}) { print(self.quesId) if selectedAnswer[row].choiceId == choiceArray[indexPath.row] { print(selectedAnswer[row].choiceId, choiceArray[indexPath.row]) cell.radioButton.isSelected = true } else { cell.radioButton.isSelected = false } } else { if indexPath == selectedButtonIndexPath { // If button is selected cell.radioButton.isSelected = true self.selectedChoiceId = choiceArray[indexPath.row] } else { // If it is not selected cell.radioButton.isSelected = false } } return cell } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: (collectionView.frame.size.width-10)/2, height: 70) } } extension UICollectionView { func deselectAllItems(animated: Bool) { guard let selectedItems = indexPathsForSelectedItems else { return } for indexPath in selectedItems { deselectItem(at: indexPath, animated: animated) } } } extension TakeQuizViewController { func saveScoreboard(levelId:Int, topicId:Int, runs:Int, wickets:Int, noOfAttempts: Int) { let url = "\(ApiUrl.BASE_URL + ApiUrl.API_SCOREBOARD)/save.json" print(url) let cookieValue = UserDefaultsConstant.getValueFromUserDefults(for: "cookieValue") ?? "" let headers: HTTPHeaders = [ "Content-Type": "application/json", "Accept": "application/json", "Cookie": "\(Constant.CookieName) = \(cookieValue)" ] print(headers) let params: Parameters? params = [ "student" : studentId, "level" : levelId, "topic" : topicId, "runs" : runs, "wickets" : wickets, "noOfAttempts" : noOfAttempts ] print(params!) AF.request(url, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers).responseJSON { response in switch response.result { case .success(let value): print(value) let scoreData = value as! NSDictionary let student = scoreData.value(forKey: "student") as! NSObject; let studentId = student.value(forKey: "id") as! NSNumber; let topic = scoreData.value(forKey: "topic") as! NSObject; let topicId = topic.value(forKey: "id") as! NSNumber; let level = scoreData.value(forKey: "level") as! NSObject; let levelId = level.value(forKey: "id") as! NSNumber; let runs = scoreData.value(forKey: "runs") as! NSNumber; let wickets = scoreData.value(forKey: "wickets") as! NSNumber; let noOfAttempts = scoreData.value(forKey: "noOfAttempts") as! NSNumber; var saveScoreModel = [SaveScoreBoard]() let id = saveScoreModel.count + 1 let newSaveScoreModel = SaveScoreBoard(id: id, levelId: Int(truncating: levelId), topicId: Int(truncating: topicId), runs: Int(truncating: runs), wickets: Int(truncating: wickets), noOfAttempts: Int(truncating: noOfAttempts), student: Int(truncating: studentId), synced: true) saveScoreModel.append(newSaveScoreModel) DBManager.sharedInstance.addData(objs: saveScoreModel) let saveScoreDB = DBManager.sharedInstance.database.objects(SaveScoreBoard.self) print("save score count") print(saveScoreDB.count) self.submitPopupView.isHidden = false case .failure(let error): print(error) } } } }