#this is needed for the debugger
UyaanDEBUG = true

###*
*
* The GraphicSelectApp Class contains all of the main features and properties for the Graphic multi select.
*
* @class GraphicSelectApp
*
* @author Justin Schlumkoski
*
* @since 06/18/2015
*
###
class window.GraphicSelectApp

   ###*
   *
   * Holds string loction of the default data file.
   *
   * @property _defaultQuestionFile
   *
   * @type {String}
   *
   * @default void 0
   *
   ###
   _defaultQuestionFile: "data/multiselectDefaultData.txt"


   ###*
   *
   * Holds string loction of the data file.
   *
   * @property _questionFile
   *
   * @type {String}
   *
   * @default void 0
   *
   ###
   _questionFile: undefined

   ###*
   *
   * Holds the parsed JSON data. Object.
   *
   * @property AppData
   *
   * @type {Object}
   *
   * @default undefined
   *
   ###
   _appData : undefined

   ###*
   *
   * Holds the number of times the activity has been played.
   *
   * @property _currentAttempts
   *
   * @type {Interger}
   *
   * @default 0
   *
   ###
   _currentAttempts: 0

   ###*
   *
   * Holds the id of the container for the activity.
   *
   * @property containerRef
   *
   * @type {String}
   *
   * @default null
   *
   ###
   _containerRef: null

   ###*
   *
   * Holds the DOm referance of the container for the activity.
   *
   * @property _appContainer
   *
   * @type {Object}
   *
   * @default void 0
   *
   ###
   _appContainer: undefined

   ###*
   *
   * Holds whether or not the activity is being accessed on a mobile device.
   *
   * @property _mobileDevice
   *
   * @type {Boolean}
   *
   * @default false
   *
   ###
   _mobileDevice : false

   ###*
   *
   * Holds whether the end report has been displayed.
   *
   * @property _finalReport
   *
   * @type {Boolean}
   *
   * @default false
   *
   ###
   _finalReport : false

   ###*
   *
   * Holds whether continuous feedback is required.
   *
   * @property _continuousFeedback
   *
   * @type {Boolean}
   *
   * @default null
   *
   ###
   _continuousFeedback : null

   ###*
   *
   * Holds whether report feedback after each question is required.
   *
   * @property _reportFeedback
   *
   * @type {Boolean}
   *
   * @default null
   *
   ###
   _reportFeedback : null

   ###*
   *
   * Holds whether an end report is required.
   *
   * @property _endReport
   *
   * @type {Boolean}
   *
   * @default null
   *
   ###
   _endReport: null,


   ###*
   *
   * Tab index - Holds the tab index.
   *
   * @property _tabIndex
   *
   * @type {Integer}
   *
   * @default 2
   *
   ###
   _tabIndex : 2

   ###*
   *
   * Holds the current question number.
   *
   * @property _currentQuestion
   *
   * @type {Integer}
   *
   * @default 0
   *
   ###
   _currentQuestion : 0

   ###*
   *
   * Holds the current page number.
   *
   * @property _pageNum
   *
   * @type {Integer}
   *
   * @default 0
   *
   ###
   _pageNum: 0

   ###*
   *
   * Holds the parameters for the restart button.
   *
   * @property _restartButton
   *
   * @type {Object}
   *
   * @default null
   *
   ###
   _restartButton: null

   ###*
   *
   * Holds the parameters for the start button.
   *
   * @property _startButton
   *
   * @type {Object}
   *
   * @default null
   *
   ###
   _startButton: null

   ###*
   *
   * Holds the parameters for the next button.
   *
   * @property _nextButton
   *
   * @type {Object}
   *
   * @default null
   *
   ###
   _nextButton: null

   ###*
   *
   * Holds the parameters for the back button.
   *
   * @property backButton
   *
   * @type {Object}
   *
   * @default null
   *
   ###
   _backButton: null

   ###*
   *
   * Holds the parameters for the instructions button.
   *
   * @property instructionButton
   *
   * @type {Object}
   *
   * @default null
   *
   ###
   _instructionButton: null

   ###*
   *
   * Holds the parameters for the submit all button.
   *
   * @property _submitAllButton
   *
   * @type {Object}
   *
   * @default null
   *
   ###
   _submitAllButton: null

   ###*
   *
   * Holds the interval used to determine if all questions have been submitted.
   *
   * @property _submitInterval
   *
   * @type {Event}
   *
   * @default null
   *
   ###
   _submitInterval: null

   ###*
   *
   * Holds whether the activity is being accessed on IE
   *
   * @property usingIE
   *
   * @type {Boolean}
   *
   * @default false
   *
   ###
   _usingIE: false

   ###*
   *
   * Temporary array used to build the array of user answers.
   *
   * @property _questionCheck
   *
   * @type {Array}
   *
   * @default empty
   *
   ###
   _questionCheck: []

   ###*
   *
   * Array that holds the users answers for each question.
   *
   * @property _allCheck
   *
   * @type {Array}
   *
   * @default empty
   *
   ###
   _allCheck: []

   ###*
   *
   * Temporary array used to build the array of correct answers.
   *
   * @property _correctAnswers
   *
   * @type {Array}
   *
   * @default empty
   *
   ###
   _correctAnswers: []

   ###*
   *
   * Array that holds the correct answers for each question.
   *
   * @property _allCorrect
   *
   * @type {Array}
   *
   * @default empty
   *
   ###
   _allCorrect: []

   ###*
   *
   * Array that holds whether each question has been submitted.
   *
   * @property _submitCheck
   *
   * @type {Array}
   *
   * @default empty
   *
   ###
   _submitCheck: []

   ###*
   *
   * base level of headings wich will be added to the app
   *
   * @property _headingLevel
   *
   * @type {Integer}
   *
   * @default 1
   *
   ###
   _headingLevel: 1

   ###*
   *
   * Constuctor will defien the binds for this class
   *
   * @method GraphicSelectApp
   *
   ###
   constructor: () ->
      return

   ###*
   *
   * Resets specified properties to their default values.
   *
   * @method resetActivityData
   *
   ###
   resetActivityData: () =>
      @_currentQuestion = 0
      @_pageNum = 0
      @_finalReport = false
      @_submitInterval = null
      @_tabIndex = 2
      @_allCheck = []
      @_allCorrect = []
      @_submitCheck = []
      return

   ###*
   *
   * Establishes the JSON text file path, the id of the container that houses the activity, and makes a call to get the activity data.
   *
   * @method setupApp
   *
   * @param {String} file
   *
   * @param {String} location
   *
   ###
   setupApp: (file, location) =>
      @_questionFile = file
      if document.getElementById(location) != null
         @_containerRef = document.getElementById(location)
         @getAppData () =>
            @getAppData @buildApp, @_questionFile
         , @_defaultQuestionFile
      else
         @Uyaanog 'Error! Missing Proper DOM object.'
      return

   ###*
   *
   * Retrieves the activity data from the JSON text file, passes that data to build the activity.
   *
   * @method getAppData
   * 
   * @param {function} callback
   *
   ###
   getAppData: (callback, fileRef) =>
      jqxhr = $.getJSON(fileRef, (data) =>
         if not @_appData
            @_appData = data
         else
            @_appData = @mergeObjectData(data.valueOf(), @_appData.valueOf())
         callback @_appData
         return
      )
      # if the json data fails inform the users and give some data to developers using the debug console.
      jqxhr.fail (e) =>
         @Uyaanog 'ERROR!!: failed to load data from specified file. Ensure file is at that location and that JSON data is vaild. (tip: use a vaildator like: http://jsonformatter.curiousconcept.com/ )'
         @Uyaanog e
         return
      return

   ###*
   *
   * Checks if the activity is being accessed on a mobile device or Internet Explorer and
   * sets up other necessary things for the entire activity.
   *
   * @method buildApp
   *
   ###
   buildApp: =>
      if /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
         @_mobileDevice = true
      @_usingIE = @msieversion()
      hl = parseInt(@_appData.HeadingLevel)
      hl = 1 if isNaN(hl) or hl < 1
      hl = 2 if hl > 2
      @_headingLevel = hl
      @_continuousFeedback = @_appData.ProvideContinuous
      @_reportFeedback = @_appData.ProvideQuestionReport
      @_endReport = @_appData.ProvideEndReport
      if @_continuousFeedback == false
         if @_appData.QuestionDisplay == 'all'
            if @_endReport == false
               @_continuousFeedback = true
         else if @_appData.QuestionDisplay == 'single'
            if @_reportFeedback == false and @_endReport == false
               @_continuousFeedback = true
      @Questions = @_appData.Questions
      if @_appData.Randomize == true
         @shuffle @Questions
      @buildAppFrame() 
      @loadButtons()
      @buildAnswerReferences()
      # @Uyaanog("User Answers: " );
      # @Uyaanog(@_allCheck);
      # @Uyaanog("Correct Answers: " );
      # @Uyaanog(@_allCorrect);
      if @_appData.PreActivityText == 'none'
         if @_appData.PreActivityMedia == 'none'
            @buildActivity()
         else
            @buildPreActivity()
      else
         @buildPreActivity()

      @HandleResizeEvent()
      return

   ###*
   *
   * Sets up the initial containers for the app.
   *
   * @method buildAppFrame
   *
   ###
   buildAppFrame: =>
      GS_container = document.createElement('section')
      GS_container.id = 'GS_container'
      #GS_container.title = "Activity Container"
      GS_content = document.createElement('section')
      GS_content.id = 'GS_content'
      #GS_content.title = "Activity Content"
      GS_header = document.createElement('section')
      GS_header.id = 'GS_header'
      #GS_header.title = "Activity Heading";
      GS_header.innerHTML = "<h#{@_headingLevel} id=\'head\'>" + @_appData.ActivityName + "</h#{@_headingLevel}>"
      GS_container.appendChild GS_content
      GS_content.appendChild GS_header
      $(GS_container).appendTo @_containerRef
      @_appContainer = document.createElement('div')
      @_appContainer.id = 'GS_appContainer'
      GS_content.appendChild @_appContainer
      return

   ###*
   *
   * Sets up all the parameters for each button and stores them in an object.
   *
   * @method loadButtons
   *
   ###
   loadButtons: =>
      GS_buttonIcon = document.createElement('div')
      GS_buttonIcon.setAttribute 'class', 'GS_buttonIcon'
      GS_restartButton = document.createElement('button')
      GS_restartButton.id = 'GS_restartButton'
      GS_restartButton.setAttribute 'class', 'GS_button'
      #GS_restartButton.setAttribute("tabindex", "0");
      GS_restartButton.setAttribute 'title', 'Restarts the Activity'

      GS_restartButton.onclick = =>
         @clearStage()
         @resetActivityData()
         @buildAnswerReferences()
         if @_appData.PreActivityText == 'none'
            if @_appData.PreActivityMedia == 'none'
               @buildActivity()
            else
               @buildPreActivity()
         else
            @buildPreActivity()
         return

      GS_restartLabel = document.createElement('span')
      GS_restartLabel.setAttribute 'class', 'GS_buttonLabel'
      GS_restartLabel.innerHTML = 'Restart Activity'
      GS_restartButton.appendChild GS_buttonIcon
      GS_restartButton.appendChild GS_restartLabel
      @_restartButton = GS_restartButton
      GS_buttonIcon = document.createElement('div')
      GS_buttonIcon.setAttribute 'class', 'GS_buttonIcon'
      GS_startButton = document.createElement('button')
      GS_startButton.id = 'GS_startButton'
      GS_startButton.setAttribute 'class', 'GS_button'
      #GS_startButton.setAttribute("tabindex", "0");
      GS_startButton.setAttribute 'title', 'Starts the Activity'

      GS_startButton.onclick = =>
         @clearStage()
         @_pageNum++
         @buildActivity()
         return

      GS_startLabel = document.createElement('span')
      GS_startLabel.setAttribute 'class', 'GS_buttonLabel'
      GS_startLabel.innerHTML = 'Start Activity'
      GS_startButton.appendChild GS_buttonIcon
      GS_startButton.appendChild GS_startLabel
      @_startButton = GS_startButton
      GS_buttonIcon = document.createElement('div')
      GS_buttonIcon.setAttribute 'class', 'GS_buttonIcon'
      GS_nextButton = document.createElement('button')
      GS_nextButton.id = 'GS_nextButton'
      GS_nextButton.setAttribute 'class', 'GS_button'
      #GS_nextButton.setAttribute("tabindex", "0");
      GS_nextButton.setAttribute 'title', 'Moves to the Next Part of the Activity'

      GS_nextButton.onclick = =>
         @_currentQuestion++
         @_pageNum++
         if @_appData.QuestionDisplay == 'single'
            if @_reportFeedback == false and @_endReport == true and @_finalReport == false
               @CheckAnswer @_currentQuestion - 1, 'next'
            if @_currentQuestion < @Questions.length
               @clearStage()
               @buildActivity()
            else
               if @_endReport == true
                  if @_finalReport == false
                     @_finalReport = true
                     @clearStage()
                     @buildReport()
                  else
                     @clearStage()
                     @buildPostActivity()
                     @_currentAttempts++
               else
                  @clearStage()
                  @buildPostActivity()
                  @_currentAttempts++
         else if @_appData.QuestionDisplay == 'all'
            i = 0
            while i < @Questions.length
               @CheckAnswer i, 'next'
               i++
            clearInterval @_submitInterval
            if @_finalReport == false
               if @_endReport == true
                  @_finalReport = true
                  @clearStage()
                  @buildReport()
               else
                  @clearStage()
                  @buildPostActivity()
                  @_currentAttempts++
            else
               @clearStage()
               @buildPostActivity()
               @_currentAttempts++
         @HandleResizeEvent()
         return

      GS_nextLabel = document.createElement('span')
      GS_nextLabel.setAttribute 'class', 'GS_buttonLabel'
      GS_nextButton.appendChild GS_buttonIcon
      GS_nextButton.appendChild GS_nextLabel
      @_nextButton = GS_nextButton
      GS_buttonIcon = document.createElement('div')
      GS_buttonIcon.setAttribute 'class', 'GS_buttonIcon'
      GS_backButton = document.createElement('button')
      GS_backButton.id = 'GS_backButton'
      GS_backButton.setAttribute 'class', 'GS_button'
      #GS_backButton.setAttribute("tabindex", "0");
      GS_backButton.setAttribute 'title', 'Moves to the Previous Part of the Activity'

      GS_backButton.onclick = =>
         @clearStage()
         @_currentQuestion--
         @_pageNum--
         if @_currentQuestion < 0
            @_currentQuestion = 0
         if @_pageNum == 0
            if @_appData.PreActivityText == 'none' and @_appData.PreActivityMedia == 'none'
               @buildActivity()
            else
               @buildPreActivity()
         else
            @buildActivity()
         return

      GS_backLabel = document.createElement('span')
      GS_backLabel.setAttribute 'class', 'GS_buttonLabel'
      GS_backLabel.innerHTML = 'Go Back'
      GS_backButton.appendChild GS_buttonIcon
      GS_backButton.appendChild GS_backLabel
      @_backButton = GS_backButton
      GS_buttonIcon = document.createElement('div')
      GS_buttonIcon.setAttribute 'class', 'GS_buttonIcon'
      GS_instructionButton = document.createElement('button')
      GS_instructionButton.id = 'GS_instructionButton'
      GS_instructionButton.alt = 'Instruction toggle'
      #GS_instructionButton.setAttribute("tabindex", "0");
      GS_instructionButton.setAttribute 'class', 'GS_button'
      GS_instructionButton.setAttribute 'title', 'Toggles the Instructions'

      GS_instructionButton.onclick = =>
         @toggleInstructions()
         return

      @_instructionButton = GS_instructionButton
      GS_buttonIcon = document.createElement('div')
      GS_buttonIcon.setAttribute 'class', 'GS_buttonIcon'
      GS_submitAllButton = document.createElement('button')
      GS_submitAllButton.id = 'GS_submitAllButton'
      GS_submitAllButton.setAttribute 'class', 'GS_button'
      GS_submitAllButton.setAttribute 'title', 'Submits all answers at once'

      GS_submitAllButton.onclick = =>
         i = 0
         while i < @Questions.length
            if document.getElementById('GS_submitButton' + i).disabled == false
               $('#GS_submitButton' + i).click()
            i++
         document.getElementById('GS_nextButton').disabled = false
         clearInterval @_submitInterval
         return

      GS_submitAllLabel = document.createElement('span')
      GS_submitAllLabel.setAttribute 'class', 'GS_buttonLabel'
      GS_submitAllLabel.innerHTML = 'Submit All'
      GS_submitAllButton.appendChild GS_buttonIcon
      GS_submitAllButton.appendChild GS_submitAllLabel
      @_submitAllButton = GS_submitAllButton
      return

   ###*
   *
   * Clears the app container.
   *
   * @method clearStage
   *
   ###
   clearStage: =>
      $('#GS_appContainer').empty()
      return

   ###*
   *
   * Builds the pre activity inside of the app container.
   *
   * @method buildPreActivity
   *
   ###
   buildPreActivity: =>
      hasImage = false
      hasVideo = false
      if @_appData.PreActivityText != 'none'
         GS_preActivityText = document.createElement('p')
         GS_preActivityText.id = 'GS_preActivityText'
         GS_preActivityText.innerHTML = @_appData.PreActivityText
         @_appContainer.appendChild GS_preActivityText
      if @_appData.PreActivityMedia != 'none'
         i = 0
         while i < @_appData.PreActivityMedia.length
            if @_appData.PreActivityMedia[i].type == 'image'
               hasImage = true
            else if @_appData.PreActivityMedia[i].type == 'YouTubeVideo'
               hasVideo = true
            @EmbedMedia 'page', @_appContainer, @_appData.PreActivityMedia[i]
            i++
      if hasVideo == false and hasImage == false
         @buildPreActivityButtons()
      else
         $('.embedMedia:last').load =>
            @buildPreActivityButtons()
            @HandleResizeEvent()
            return
      $('#head').attr('tabindex', '1').css 'outline', 'none'
      $('#head').focus()
      return

   ###*
   *
   * Adds the button(s) for the pre activity into the app container.
   *
   * @method buildPreActivityButtons
   *
   ###
   buildPreActivityButtons: =>
      GS_buttonSet = document.createElement('div')
      GS_buttonSet.id = 'GS_buttonSet'
      @_appContainer.appendChild GS_buttonSet
      GS_buttonSet.appendChild @_startButton
      return

   ###*
   *
   * Builds the post activity inside of the app container.
   *
   * @method buildPostActivity
   *
   ###
   buildPostActivity: =>
      hasImage = false
      hasVideo = false
      GS_postActivityText = undefined
      if @_appData.PostActivityText != 'none'
         GS_postActivityText = document.createElement('p')
         GS_postActivityText.id = 'GS_postActivityText'
         GS_postActivityText.innerHTML = @_appData.PostActivityText
         @_appContainer.appendChild GS_postActivityText
      else
         GS_postActivityText = document.createElement('p')
         GS_postActivityText.id = 'GS_postActivityText'
         GS_postActivityText.innerHTML = 'You have completed the activity!'
         @_appContainer.appendChild GS_postActivityText
      if @_appData.PostActivityMedia != 'none'
         i = 0
         while i < @_appData.PostActivityMedia.length
            if @_appData.PostActivityMedia[i].type == 'image'
               hasImage = true
            else if @_appData.PostActivityMedia[i].type == 'YouTubeVideo'
               hasVideo = true
            @EmbedMedia 'page', @_appContainer, @_appData.PostActivityMedia[i]
            i++
      if hasVideo == false and hasImage == false
         @buildPostActivityButtons()
      else
         $('.embedMedia:last').load =>
            @buildPostActivityButtons()
            @HandleResizeEvent()
            return
      $('#head').attr('tabindex', '1').css 'outline', 'none'
      $('#head').focus()
      return

   ###*
   *
   * Adds the button(s) for the post activity into the app container.
   *
   * @method buildPostActivityButtons
   *
   ###
   buildPostActivityButtons: =>
      GS_buttonSet = document.createElement('div')
      GS_buttonSet.id = 'GS_buttonSet'
      @_appContainer.appendChild GS_buttonSet
      GS_buttonSet.appendChild @_restartButton
      return

   ###*
   *
   * Builds the current activity and adds it to the app container.
   *
   * @method buildActivity
   *
   ###
   buildActivity: =>
      hasImage = false
      if @_appData.QuestionDisplay == 'all' and @_continuousFeedback == true and @_endReport == false
         i = 0
         while i < @Questions.length
            @_submitCheck.push false
            i++
         @_submitInterval = setInterval(@CheckAllSubmits, 250)
      @_tabIndex = 2
      GS_instructions = document.createElement('p')
      GS_instructions.id = 'GS_instructions'
      GS_instructions.innerHTML = @_appData.Instructions
      @_appContainer.appendChild GS_instructions
      @buildInstructions()
      @buildTable()
      @addQuestions()
      j = 0
      while j < @_appData.Answers.length
         temp = document.getElementById('head' + j)
         if $(temp.firstChild).hasClass('tableHeadImage')
            hasImage = true
         j++
      if hasImage == true
         $('.tableHeadImage:last').load =>
            @buildActivityButtons()
            return
      else if hasImage == false
         @buildActivityButtons()
      $('#head').attr('tabindex', '1').css 'outline', 'none'
      $('#head').focus()
      return

   ###*
   *
   * Adds the button(s) for the current activity into the app container.
   *
   * @method buildActivityButtons
   *
   ###
   buildActivityButtons: =>
      GS_buttonSet = document.createElement('div')
      GS_buttonSet.id = 'GS_buttonSet'
      @_appContainer.appendChild GS_buttonSet
      if @_appData.AllowPrevious == true and @_appData.QuestionDisplay == 'single'
         if @_pageNum > 0
            GS_buttonSet.appendChild @_backButton
      if @_appData.QuestionDisplay == 'all' and @_appData.SubmitAll == true
         GS_buttonSet.appendChild @_submitAllButton
      GS_buttonSet.appendChild @_nextButton
      if @_appData.QuestionDisplay == 'single'
         if @_continuousFeedback == false and @_reportFeedback == false and @_endReport == true
            document.getElementById('GS_nextButton').disabled = false
         else
            document.getElementById('GS_nextButton').disabled = true
      else if @_appData.QuestionDisplay == 'all' and @_continuousFeedback == true and @_endReport == false
         document.getElementById('GS_nextButton').disabled = true
      if @_appData.QuestionDisplay == 'single'
         if @_currentQuestion < @Questions.length - 1
            document.getElementById('GS_nextButton').lastChild.innerHTML = 'Next Question'
         else
            document.getElementById('GS_nextButton').lastChild.innerHTML = 'Finish Activity'
      else if @_appData.QuestionDisplay == 'all'
         document.getElementById('GS_nextButton').lastChild.innerHTML = 'Finish Activity'

      @HandleResizeEvent()
      return

   ###*
   *
   * Changes whether the instructions text is visible or not.
   *
   * @method toggleInstructions
   *
   ###
   toggleInstructions: () =>
      $('#GS_instructionsToggle').toggle()
      $('#GS_instructionsToggle').focus()
      $('#GS_instructionsToggle').attr 'role', 'alert'
      $('#GS_instructionsToggle').attr 'aria-live', 'assertive'
      @HandleResizeEvent()
      return

   ###*
   *
   * Builds the correct instructions based on the type of activity and the type of feedback. This is because depending on
   * the setup certain buttons/elements may or may not be present.
   *
   * @method buildInstructions
   *
   ###
   buildInstructions: =>
      GS_instructionButtonSet = document.createElement('div')
      GS_instructionButtonSet.id = 'GS_instructionButtonSet'
      @_appContainer.appendChild GS_instructionButtonSet
      @_instructionButton.setAttribute 'tabindex', @_tabIndex
      @_tabIndex++
      GS_instructionButtonSet.appendChild @_instructionButton
      GS_instructions = document.createElement('div')
      GS_instructions.id = 'GS_instructionsToggle'
      GS_instructions.setAttribute 'class', 'toggledOff'
      GS_instructionText = document.createElement('p')
      GS_instructionText.id = 'GS_instructionText'
      GS_instructionText.setAttribute 'class', 'tooltip'
      # Default text for keyboard controls that will be added to all instructions

      if @_appData.QuestionDisplay == 'single'
         if @_continuousFeedback == false and @_reportFeedback == false and @_endReport == true
            GS_instructionText.innerHTML = "#{@_appData.Instruct_common} #{@_appData.Instruct_01} <br><br> #{@_appData.Instructions_KeyUserText}"
         else
            GS_instructionText.innerHTML = "#{@_appData.Instruct_common} #{@_appData.Instruct_02} <br><br> #{@_appData.Instructions_KeyUserText}"
      else if @_appData.QuestionDisplay == 'all'
         if @_continuousFeedback == true and @_endReport == false
            GS_instructionText.innerHTML = "#{@_appData.Instruct_common} #{@_appData.Instruct_03} <br><br> #{@_appData.Instructions_KeyUserText}"
         else
            GS_instructionText.innerHTML = "#{@_appData.Instruct_common} #{@_appData.Instruct_04} <br><br> #{@_appData.Instructions_KeyUserText}"
      GS_instructions.appendChild GS_instructionText
      $(GS_instructions).insertBefore '#GS_instructionButtonSet'
      $('#GS_instructionsToggle').toggle()
      return

   ###*
   *
   * Builds the table for the activity. It also adds the questions and table name into the first row of the table.
   *
   * @method buildTable
   *
   ###
   buildTable: =>
      GS_tableContainer = document.createElement('div')
      tempTD = undefined
      GS_tableContainer.id = 'GS_tableContainer'
      GS_table = document.createElement('table')
      GS_table.id = 'GS_table'
      #GS_table.setAttribute("role", "presentation");
      GS_tHead = document.createElement('thead')
      GS_tHead.id = 'GS_tHead'
      GS_tRow = document.createElement('tr')
      GS_tRow.setAttribute 'class', 'GS_tRow'
      GS_tHeading = document.createElement('th')
      GS_tHeading.id = 'GS_tHeading'
      GS_tHeading.innerHTML = '<strong>' + @_appData.TableHeading + '</strong>'
      GS_tHeading.setAttribute 'scope', 'col'
      if @_usingIE == true
         GS_tHeading.setAttribute 'title', @_appData.TableHeading
      GS_tHeading.setAttribute 'tabindex', @_tabIndex
      @_tabIndex++
      GS_tRow.appendChild GS_tHeading
      i = 0
      while i < @_appData.Answers.length
         tempTD = document.createElement('th')
         tempTD.id = 'head' + i
         tempTD.setAttribute 'class', 'GS_tAnswer'
         tempTD.setAttribute 'scope', 'col'
         if @_usingIE == true
            tempTD.title = @_appData.Answers[i].text
         tempTD.setAttribute 'tabindex', @_tabIndex
         @_tabIndex++
         if @_appData.Answers[i].imgSrc != 'none' and @_appData.Answers[i].imgSrc != null and @_appData.Answers[i].imgSrc != undefined and @_appData.Answers[i].imgSrc != ''
            tempImg = document.createElement('img')
            tempImg.src = @_appData.Answers[i].imgSrc
            tempImg.alt = @_appData.Answers[i].alt
            tempImg.setAttribute 'class', 'tableHeadImage'
            tempTD.appendChild tempImg
         tempText = document.createElement('p')
         tempText.innerHTML = @_appData.Answers[i].text
         tempTD.appendChild tempText
         GS_tRow.appendChild tempTD
         i++
      GS_tResults = document.createElement('th')
      GS_tResults.id = 'GS_tResults'
      GS_tResults.setAttribute 'scope', 'col'
      GS_tResults.setAttribute 'tabindex', @_tabIndex
      @_tabIndex++
      GS_tRow.appendChild GS_tResults
      GS_tHead.appendChild GS_tRow
      GS_table.appendChild GS_tHead
      GS_tableContainer.appendChild GS_table
      @_appContainer.appendChild GS_tableContainer
      return

   ###*
   *
   * Depending on the how the activity was configured, it adds the appropriate number if question(s) to the table, the checkboxes
   * and the buttons associated with each question.
   *
   * @method addQuestions
   *
   ###
   addQuestions: =>
      tempTD = undefined
      tempRow = undefined
      tempTitle = undefined
      tempInput = undefined
      tempQuestionCont = undefined
      tempQuestion = undefined
      tempResults = undefined
      GS_tBody = undefined
      GS_submitButton = undefined
      GS_submitLabel = undefined
      GS_resetButton = undefined
      GS_resetLabel = undefined
      j = undefined
      # common itorator
      GS_tBody = document.createElement('tbody')
      GS_tBody.id = 'GS_tBody'
      GS_table = $('#GS_table')[0]
      if @_appData.QuestionDisplay == 'all'
         i = 0
         while i < @Questions.length
            tempRow = document.createElement('tr')
            tempRow.id = 'row' + i
            tempRow.setAttribute 'class', 'GS_tRow'
            tempQuestionCont = document.createElement('th')
            tempQuestionCont.id = 'question' + i
            tempQuestionCont.setAttribute 'class', 'GS_tQuestion'
            tempQuestionCont.setAttribute 'scope', 'row'
            if @_usingIE == true
               if @_appData.NumberedQuestions == true
                  tempQuestionCont.setAttribute 'title', i + 1 + '. ' + @Questions[i].text
               else
                  tempQuestionCont.setAttribute 'title', @Questions[i].text
            tempQuestionCont.setAttribute 'tabindex', @_tabIndex
            @_tabIndex++
            if i == @Questions.length - 1
               $(tempQuestionCont).addClass 'last'
            tempQuestion = document.createElement('p')
            if @_appData.NumberedQuestions == true
               tempQuestion.innerHTML = i + 1 + '. ' + @Questions[i].text
            else
               tempQuestion.innerHTML = @Questions[i].text
            tempQuestionCont.appendChild tempQuestion
            tempRow.appendChild tempQuestionCont
            j = 0
            while j < @_appData.Answers.length
               tempTD = document.createElement('td')
               tempTD.id = 'GS_tCheck' + i + j
               tempTD.setAttribute 'class', 'GS_tCheckBox'
               if i == @Questions.length - 1
                  $(tempTD).addClass 'last'
               tempTitle = document.createElement('p')
               tempTitle.setAttribute 'class', 'GS_feedback'
               tempTitle.innerHTML = 'Your Answer:'
               tempInput = document.createElement('div')
               tempInput.id = 'checkbox' + i + j
               tempInput.setAttribute 'class', 'GS_tInput check'
               tempInput.setAttribute 'role', 'checkbox'
               tempInput.setAttribute 'aria-checked', 'false'
               tempInput.setAttribute 'tabindex', @_tabIndex
               @_tabIndex++

               tempInput.onclick = (e) =>
                  @HandleSelection e
                  return

               tempInput.onkeydown = (e) =>
                  if e.which == 13 or e.which == 32
                     @HandleSelection e
                  return

               tempTD.appendChild tempTitle
               tempTD.appendChild tempInput
               tempRow.appendChild tempTD
               j++
            tempResults = document.createElement('td')
            tempResults.id = 'results' + i
            tempResults.setAttribute 'class', 'GS_tQuestionResults'
            if i == @Questions.length - 1
               $(tempResults).addClass 'last'
            if @_continuousFeedback == true
               GS_submitButton = document.createElement('button')
               GS_submitButton.id = 'GS_submitButton' + i
               GS_submitButton.setAttribute 'class', 'GS_resultButton'
               GS_submitButton.setAttribute 'title', 'Submits your answer'
               GS_submitButton.setAttribute 'tabindex', @_tabIndex
               @_tabIndex++

               GS_submitButton.onclick = () ->
                  appRef = window.application
                  appRef.CheckAnswer this, 'submit'
                  numRef = this.id.substr(15)
                  appRef._submitCheck.splice numRef, 1, true
                  return

               GS_submitLabel = document.createElement('span')
               GS_submitLabel.setAttribute 'class', 'GS_buttonLabel'
               GS_submitLabel.innerHTML = 'Submit'
               GS_submitButton.appendChild GS_submitLabel
               tempResults.appendChild GS_submitButton
            GS_resetButton = document.createElement('button')
            GS_resetButton.id = 'GS_resetButton' + i
            GS_resetButton.setAttribute 'class', 'GS_resultButton'
            GS_resetButton.setAttribute 'title', 'Resets your answer'
            GS_resetButton.setAttribute 'tabindex', @_tabIndex
            @_tabIndex += 2

            GS_resetButton.onclick = () ->
               appRef = window.application
               appRef.ResetQuestionAnswers this
               numRef = this.id.substr(14)
               appRef._submitCheck.splice numRef, 1, false
               return

            GS_resetLabel = document.createElement('span')
            GS_resetLabel.setAttribute 'class', 'GS_buttonLabel'
            GS_resetLabel.innerHTML = 'Reset Answers'
            GS_resetButton.appendChild GS_resetLabel
            tempResults.appendChild GS_resetButton
            tempRow.appendChild tempResults
            GS_tBody.appendChild tempRow
            GS_table.appendChild GS_tBody
            i++
      else if @_appData.QuestionDisplay == 'single'
         tempRow = document.createElement('tr')
         tempRow.id = 'row' + @_currentQuestion
         tempRow.setAttribute 'class', 'GS_tRow'
         tempQuestionCont = document.createElement('th')
         tempQuestionCont.id = 'question' + @_currentQuestion
         tempQuestionCont.setAttribute 'class', 'GS_tQuestion'
         tempQuestionCont.setAttribute 'scope', 'row'
         tempQuestionCont.setAttribute 'tabindex', @_tabIndex
         @_tabIndex++
         $(tempQuestionCont).addClass 'last'
         tempQuestion = document.createElement('p')
         tempQuestion.innerHTML = @_currentQuestion + 1 + '. ' + @Questions[@_currentQuestion].text
         tempQuestionCont.appendChild tempQuestion
         tempRow.appendChild tempQuestionCont
         j = 0
         while j < @_appData.Answers.length
            tempTD = document.createElement('td')
            tempTD.id = 'GS_tCheck' + @_currentQuestion + j
            tempTD.setAttribute 'class', 'GS_tCheckBox'
            $(tempTD).addClass 'last'
            tempTitle = document.createElement('p')
            tempTitle.setAttribute 'class', 'GS_feedback'
            tempTitle.innerHTML = 'Your Answer:'
            tempInput = document.createElement('div')
            tempInput.id = 'checkbox' + @_currentQuestion + j
            tempInput.setAttribute 'class', 'GS_tInput check'
            tempInput.setAttribute 'role', 'checkbox'
            tempInput.setAttribute 'aria-checked', 'false'
            tempInput.setAttribute 'tabindex', @_tabIndex
            tempInput.setAttribute 'onclick', 'window.application.HandleSelection(event)'
            tempInput.setAttribute 'onkeydown', 'window.application.HandleKeyboardSelection(event)'
            if @_allCheck[@_currentQuestion][j] == true
               $(tempInput).addClass 'selected'
            @_tabIndex++
            tempTD.appendChild tempTitle
            tempTD.appendChild tempInput
            tempRow.appendChild tempTD
            j++
         tempResults = document.createElement('td')
         tempResults.id = 'results' + @_currentQuestion
         tempResults.setAttribute 'class', 'GS_tQuestionResults'
         $(tempResults).addClass 'last'
         if @_continuousFeedback == true or @_reportFeedback == true
            GS_submitButton = document.createElement('button')
            GS_submitButton.id = 'GS_submitButton' + @_currentQuestion
            GS_submitButton.setAttribute 'class', 'GS_resultButton'
            GS_submitButton.setAttribute 'title', 'Submits your answer'
            GS_submitButton.setAttribute 'tabindex', @_tabIndex
            @_tabIndex++

            GS_submitButton.onclick = () ->
               appRef = window.application
               appRef.CheckAnswer this, 'submit'
               if appRef._reportFeedback == true
                  if $('#GS_report' + this.id.substr(15)).length
                     $('#GS_report' + this.id.substr(15)).remove()
                  appRef.BuildMiniReport this.id.substr(15)
               document.getElementById('GS_nextButton').disabled = false
               return

            GS_submitLabel = document.createElement('span')
            GS_submitLabel.setAttribute 'class', 'GS_buttonLabel'
            GS_submitLabel.innerHTML = 'Submit'
            GS_submitButton.appendChild GS_submitLabel
            tempResults.appendChild GS_submitButton
         GS_resetButton = document.createElement('button')
         GS_resetButton.id = 'GS_resetButton' + @_currentQuestion
         GS_resetButton.setAttribute 'class', 'GS_resultButton'
         GS_resetButton.setAttribute 'title', 'Resets your answer'
         GS_resetButton.setAttribute 'tabindex', @_tabIndex
         @_tabIndex += 2

         GS_resetButton.onclick = () ->
            appRef = window.application
            appRef.ResetQuestionAnswers this
            if appRef._reportFeedback == true
               if $('#GS_report' + this.id.substr(14)).length
                  $('#GS_report' + this.id.substr(14)).remove()
            if appRef._appData.QuestionDisplay == 'single'
               if appRef._continuousFeedback == false and appRef._reportFeedback == false and appRef._endReport == true
                  document.getElementById('GS_nextButton').disabled = false
               else
                  document.getElementById('GS_nextButton').disabled = true
            appRef.HandleResizeEvent()
            return

         GS_resetLabel = document.createElement('span')
         GS_resetLabel.setAttribute 'class', 'GS_buttonLabel'
         GS_resetLabel.innerHTML = 'Reset Answers'
         GS_resetButton.appendChild GS_resetLabel
         tempResults.appendChild GS_resetButton
         tempRow.appendChild tempResults
         GS_tBody.appendChild tempRow
         GS_table.appendChild GS_tBody
      return

   ###*
   *
   * Depending on the checkbox you clicked on, it determines whether it should be checked/unchecked, and adjusts it accordingly.
   *
   * @method HandleSelection
   *
   * @param {event} e
   *
   ###
   HandleSelection: (e) =>
      selectedBox = e.target
      if $(selectedBox).hasClass('check')
         if $(selectedBox).hasClass('selected')
            $(selectedBox).removeClass 'selected'
            selectedBox.setAttribute 'aria-checked', 'false'
         else
            $(selectedBox).addClass 'selected'
            selectedBox.setAttribute 'aria-checked', 'true'
      return

   ###*
   *
   * Takes a keyboard event performed on a checkbox, and determines if it was an enter or spacebar.
   * If so, it handles the selection accordingly.
   *
   * @method HandleKeyboardSelection
   *
   * @param {event} e
   *
   ###
   HandleKeyboardSelection: (e) =>
      if e.which == 13 or e.which == 32
         @HandleSelection e
      return

   ###*
   *
   * Depending on the button that made the call, it saves the users answers accordingly.
   *
   * @method CheckAnswer
   *
   * @param {Object} target
   * @param {String} button, type of button that made call
   *
   ###
   CheckAnswer: (target, button) =>
      id = undefined
      idNum = undefined
      if button == 'next'
         idNum = target
      else if button == 'submit'
         id = target.id
         idNum = id.substr(15)
      else if button == 'submitAll'
         idNum = target
         document.getElementById('GS_nextButton').disabled = false
      i = 0
      while i < @_appData.Answers.length
         temp = document.getElementById('checkbox' + idNum + i)
         if $(temp).hasClass('selected') == true
            @_allCheck[idNum].splice i, 1, true
         else
            @_allCheck[idNum].splice i, 1, false
         i++
      if button == 'submit' or button == 'submitAll'
         if @_continuousFeedback == true
            @GenerateQuestionFeedback idNum
      return

   ###*
   *
   * Resets all the checkboxes to an unchecked state.
   *
   * @method ResetQuestionAnswers
   *
   * @param {Object} target
   *
   ###
   ResetQuestionAnswers: (target) =>
      id = target.id
      idNum = id.substr(14)
      i = 0
      while i < @_appData.Answers.length
         # if ($(document.getElementById("GS_tCheck" + idNum + i).lastChild).hasClass("GS_qRes") === true) {
         #    $(document.getElementById("GS_qRes" + idNum + i)).remove();
         # }
         if $(document.getElementById('GS_tCheck' + idNum + i).lastChild).hasClass('GS_corrAnsImg') == true
            $(document.getElementById('GS_tCheck' + idNum + i).lastChild).remove()
         if $(document.getElementById('GS_tCheck' + idNum + i).lastChild).hasClass('GS_feedback') == true
            $(document.getElementById('GS_tCheck' + idNum + i).lastChild).remove()
         tempBox = document.getElementById('GS_tCheck' + idNum + i).lastChild
         tempBox.removeAttribute 'title'
         tempBox.setAttribute 'class', 'GS_tInput check'
         tempBox.setAttribute 'role', 'checkbox'
         tempBox.setAttribute 'aria-checked', 'false'
         tempBox.setAttribute 'onclick', 'application.HandleSelection(event)'
         tempBox.setAttribute 'onkeydown', 'application.HandleKeyboardSelection(event)'
         $('.GS_tInput').css 'cursor', 'pointer'
         i++
      if $(document.getElementById('results' + idNum).lastChild).hasClass('GS_feedback') == true
         $(document.getElementById('GS_qFeedback' + idNum)).remove()
      if document.getElementById('GS_submitButton' + idNum)
         document.getElementById('GS_submitButton' + idNum).disabled = false 
      return

   ###*
   *
   * Takes the question number and builds continuous feedback for that question based on the user's answers.
   *
   * @method GenerateQuestionFeedback
   *
   * @param {Integer} qNum
   *
   ###
   GenerateQuestionFeedback: (qNum) =>
      tempTitle = undefined
      corrAns = undefined
      questionScore = 0
      resultCont = document.getElementById('results' + qNum)
      document.getElementById('GS_submitButton' + qNum).disabled = true
      $('#GS_resetButton' + qNum).focus()
      i = 0
      while i < @_appData.Answers.length
         box = document.getElementById('GS_tCheck' + qNum + i).lastChild
         if @_allCheck[qNum][i] == @_allCorrect[qNum][i]
            questionScore++
            # if ($(document.getElementById("GS_tCheck" + qNum + i).lastChild).hasClass("GS_qRes") === true){
            #    $(document.getElementById("GS_qRes" + qNum + i)).remove();
            # }
            box.setAttribute 'class', 'GS_tInput'
            if @_allCheck[qNum][i] == true
               $(box).addClass 'selected'
               box.setAttribute 'title', 'Selected checkbox graphic. Correctly answered.'
            else
               box.setAttribute 'title', 'Unselected checkbox graphic. Correctly answered.'
            box.removeAttribute 'role'
            box.removeAttribute 'aria-checked'
            box.removeAttribute 'onclick'
            box.removeAttribute 'onkeydown'
            $('.GS_tInput').css 'cursor', 'default'
            if @_appData.VisualFeedback == true
               $(box).addClass 'correct'
            tempTitle = document.createElement('p')
            tempTitle.setAttribute 'class', 'GS_feedback'
            tempTitle.innerHTML = 'Correct Answer:'
            document.getElementById('GS_tCheck' + qNum + i).appendChild tempTitle
            corrAns = document.createElement('img')
            corrAns.setAttribute 'class', 'GS_corrAnsImg'
            if @_allCorrect[qNum][i] == true
               corrAns.src = 'img/icon-checked-24.png'
               corrAns.alt = 'Selected checkbox graphic'
               document.getElementById('GS_tCheck' + qNum + i).appendChild corrAns
            else
               corrAns.src = 'img/icon-unchecked-24.png'
               corrAns.alt = 'Unselected checkbox graphic'
               document.getElementById('GS_tCheck' + qNum + i).appendChild corrAns
            # var qFeed = document.createElement("p");
            # qFeed.id = "GS_qRes" + qNum + i;
            # qFeed.setAttribute("class", "GS_qRes");
            # qFeed.innerHTML = "<img src='graphics/Right_16.png' alt='Right Answer Graphic.' /> Correct";
            # document.getElementById("GS_tCheck" + qNum + i).appendChild(qFeed);
         else
            # if ($(document.getElementById("GS_tCheck" + qNum + i).lastChild).hasClass("GS_qRes") === true){
            #    $(document.getElementById("GS_qRes" + qNum + i)).remove();
            # }
            box.setAttribute 'class', 'GS_tInput'
            if @_allCheck[qNum][i] == true
               $(box).addClass 'selected'
               box.setAttribute 'title', 'Selected checkbox graphic. Incorrectly answered.'
            else
               box.setAttribute 'title', 'Unselected checkbox graphic. Incorrectly answered.'
            box.removeAttribute 'role'
            box.removeAttribute 'aria-checked'
            box.removeAttribute 'onclick'
            box.removeAttribute 'onkeydown'
            $('.GS_tInput').css 'cursor', 'default'
            if @_appData.VisualFeedback == true
               $(box).addClass 'wrong'
            tempTitle = document.createElement('p')
            tempTitle.setAttribute 'class', 'GS_feedback'
            tempTitle.innerHTML = 'Correct Answer:'
            document.getElementById('GS_tCheck' + qNum + i).appendChild tempTitle
            corrAns = document.createElement('img')
            corrAns.setAttribute 'class', 'GS_corrAnsImg'
            if @_allCorrect[qNum][i] == true
               corrAns.src = 'img/icon-checked-24.png'
               corrAns.alt = 'Selected checkbox graphic'
               document.getElementById('GS_tCheck' + qNum + i).appendChild corrAns
            else
               corrAns.src = 'img/icon-unchecked-24.png'
               corrAns.alt = 'Unselected checkbox graphic'
               document.getElementById('GS_tCheck' + qNum + i).appendChild corrAns
            # var qFeed = document.createElement("p");
            # qFeed.id = "GS_qRes" + qNum + i;
            # qFeed.setAttribute("class", "GS_qRes");
            # qFeed.innerHTML = "<img src='graphics/Wrong_16.png' alt='Wrong Answer Graphic.' /> Incorrect";
            # document.getElementById("GS_tCheck" + qNum + i).appendChild(qFeed);
         i++
      if $(resultCont.lastChild).hasClass('GS_feedback') == true
         $(document.getElementById('GS_qFeedback' + qNum)).remove()
      tabRef = document.getElementById('GS_resetButton' + qNum)
      contFeed = document.createElement('p')
      contFeed.id = 'GS_qFeedback' + qNum
      contFeed.setAttribute 'class', 'GS_feedback'
      contFeed.setAttribute 'tabindex', tabRef.tabIndex + 1
      contFeed.setAttribute 'role', 'alert'
      contFeed.setAttribute 'aria-live', 'assertive'
      contFeed.innerHTML = questionScore + ' / ' + @_appData.Answers.length + ' Correct.'
      resultCont.appendChild contFeed
      return

   ###*
   *
   * Takes the question number and builds a report for that question based on the user's answers.
   *
   * @method BuildMiniReport
   *
   * @param {Integer} qNum
   *
   ###
   BuildMiniReport: (qNum) =>
      GS_questionHead = undefined
      GS_report = document.createElement('div')
      GS_report.id = 'GS_report' + qNum
      GS_report.setAttribute 'class', 'GS_report'
      if @_finalReport == true
         GS_questionHead = document.createElement("h#{@_headingLevel+1}")
         GS_questionHead.setAttribute 'class', 'GS_questionHead'
         GS_questionHead.innerHTML = 'Question: ' + @Questions[qNum].text
      GS_ResponseText = document.createElement("h#{@_headingLevel+2}")
      GS_ResponseText.setAttribute 'class', 'GS_responseText'
      RespImg = document.createElement('img')
      RespImg.setAttribute 'class', 'GS_responseGraphic'
      RespCntx = document.createElement('strong')
      qScore = @GetQuestionScore(qNum)
      maxScore = @_appData.Answers.length
      if qScore >= maxScore
         RespImg.setAttribute 'src', 'img/icon-right-24.png'
         RespImg.setAttribute 'alt', 'Right Answer Graphic.'
         RespCntx.innerHTML = 'Your answer was correct. You scored ' + qScore + ' of a possible ' + maxScore + ' on this question.'
      else if qScore == 0
         RespImg.setAttribute 'src', 'img/icon-wrong-24.png'
         RespImg.setAttribute 'alt', 'Wrong Answer Graphic'
         RespCntx.innerHTML = 'Your answer was not correct. You scored ' + qScore + ' of a possible ' + maxScore + ' on this question.'
      else
         RespImg.setAttribute 'src', 'img/icon-partial-24.png'
         RespImg.setAttribute 'alt', 'Partially Correct Answer Graphic'
         RespCntx.innerHTML = 'Your answer was partially correct. You scored ' + qScore + ' of a possible ' + maxScore + ' on this question.'
      GS_ResponseText.appendChild RespImg
      GS_ResponseText.appendChild RespCntx
      if @_finalReport == true
         GS_report.appendChild GS_questionHead
      GS_report.appendChild GS_ResponseText
      if @_finalReport == true
         @_appContainer.appendChild GS_report
      else
         $(GS_report).insertAfter $('#GS_tableContainer')
      if qScore < maxScore
         @BuildResultTable qNum
      @BuildFeedback qNum, GS_report
      @HandleResizeEvent()
      return

   ###*
   *
   * Takes the question number and calculates the number of correct answers for that question.
   *
   * @method GetQuestionScore
   *
   * @param {Integer} qNum, question number
   *
   * @return {Interger} Returns number of correct answers for that question.
   *
   ###
   GetQuestionScore: (qNum) =>
      score = 0
      i = 0
      while i < @_appData.Answers.length
         if @_allCheck[qNum][i] == @_allCorrect[qNum][i]
            score++
         i++
      score

   ###*
   *
   * Takes the question number and builds a table comparing the user's answers for that question to the correct answers.
   *
   * @method BuildResultTable
   *
   * @param {Integer} qNum, question number
   *
   ###
   BuildResultTable: (qNum) =>
      location = document.getElementById('GS_report' + qNum)
      tableCont = document.createElement('div')
      tableCont.id = 'GS_resultTableContainer' + qNum
      table = document.createElement('table')
      table.id = 'GS_resultTable' + qNum
      table.setAttribute 'class', 'GS_resultTable'
      #table.setAttribute("role", "grid");
      head = document.createElement('thead')
      head.id = 'GS_resultTableHead' + qNum
      row = document.createElement('tr')
      row.setAttribute 'class', 'GS_tRow'
      userAnswers = document.createElement('th')
      userAnswers.id = 'GS_user' + qNum
      userAnswers.setAttribute 'class', 'GS_resultUser'
      userAnswers.setAttribute 'scope', 'col'
      userAnswers.innerHTML = '<strong>Your Answers</strong>'
      row.appendChild userAnswers
      correctAnswers = document.createElement('th')
      correctAnswers.id = 'GS_correct' + qNum
      correctAnswers.setAttribute 'class', 'GS_resultCorrect'
      correctAnswers.setAttribute 'scope', 'col'
      correctAnswers.innerHTML = '<strong>Results</stong>'
      row.appendChild correctAnswers
      head.appendChild row
      table.appendChild head
      body = document.createElement('tbody')
      body.id = 'GS_resultTableBody' + qNum
      i = 0
      while i < @_appData.Answers.length
         checkedBox = '<img src=\'img/icon-checked-24.png\' class=\'GS_reportIcon\' alt=\'Checked Box Graphic\' />'
         uncheckedBox = '<img src=\'img/icon-unchecked-24.png\' class=\'GS_reportIcon\' alt=\'Unchecked Box Graphic\' />'
         right = '<img src=\'img/icon-right-24.png\' class=\'GS_reportIcon\' alt=\'Right Answer Graphic\' />'
         wrong = '<img src=\'img/icon-wrong-24.png\' class=\'GS_reportIcon\' alt=\'Wrong Answer Graphic\' />'
         checked = undefined
         feedback = undefined
         row = document.createElement('tr')
         row.id = 'resultRow' + qNum + i
         user = document.createElement('td')
         user.id = 'userAnswer' + qNum + i
         user.setAttribute 'class', 'GS_userAnswer'
         if @_allCheck[qNum][i] == true
            checked = checkedBox
         else
            checked = uncheckedBox
         user.innerHTML = checked + '<p class=\'GS_reportText\'>' + @_appData.Answers[i].text + '</p>'
         if i == @_appData.Answers.length - 1
            $(user).addClass 'last'
         correct = document.createElement('td')
         correct.id = 'correctAnswer' + qNum + i
         correct.setAttribute 'class', 'GS_correctAnswer'
         if @_allCheck[qNum][i] == @_allCorrect[qNum][i]
            feedback = right + '<p class=\'GS_reportText\'>Correct</p>'
         else
            feedback = wrong + '<p class=\'GS_reportText\'>Incorrect</p>'
         correct.innerHTML = feedback
         if i == @_appData.Answers.length - 1
            $(correct).addClass 'last'
         row.appendChild user
         row.appendChild correct
         body.appendChild row
         i++
      table.appendChild body
      tableCont.appendChild table
      location.appendChild tableCont
      return

   ###*
   *
   * Based on the question number, it determines if the answer was wrong. If so, it determines if it requires feedback.
   * If so, it provides said feedback.
   *
   * @method BuildFeedback
   *
   * @param {Integer} qNum, question number
   * @param {Object} location
   *
   ###
   BuildFeedback: (qNum, location) =>
      noFeedback = true
      GS_feedbackCont = document.createElement('div')
      GS_feedbackCont.id = 'GS_feedbackCont' + qNum
      GS_feedbackCont.setAttribute 'class', 'GS_feedbackCont'
      GS_feedbackHead = document.createElement("h#{@_headingLevel+2}")
      GS_feedbackHead.setAttribute 'class', 'GS_feedbackHead'
      GS_feedbackHead.innerHTML = 'Feedback: '
      GS_feedbackCont.appendChild GS_feedbackHead
      if @_appData.ShowQuestionFeedback == true
         if @Questions[qNum].questionFeedback != null and @Questions[qNum].questionFeedback != undefined and @Questions[qNum].questionFeedback != 'none' and @Questions[qNum].questionFeedback != ''
            GS_feedback = document.createElement('p')
            GS_feedback.innerHTML = @Questions[qNum].questionFeedback
            GS_feedbackCont.appendChild GS_feedback
            noFeedback = false
      i = 0
      while i < @Questions[qNum].answers.length
         if @_allCheck[qNum][i] != @_allCorrect[qNum][i]
            option = document.createElement("h#{@_headingLevel+3}")
            option.setAttribute 'class', 'GS_option'
            option.innerHTML = @_appData.Answers[i].text + ': '
            if @Questions[qNum].answers[i].feedback != 'none' and @Questions[qNum].answers[i].feedback != null and @Questions[qNum].answers[i].feedback != undefined and @Questions[qNum].answers[i].feedback != ''
                           j = 0
               while j < @Questions[qNum].answers[i].feedback.length
                  GS_feedbackCont.appendChild option
                  @EmbedMedia 'feedback', GS_feedbackCont, @Questions[qNum].answers[i].feedback[j]
                  noFeedback = false
                  j++
         i++
      if noFeedback == false
         location.appendChild GS_feedbackCont
      return

   ###*
   *
   * Builds the end report for the entire quiz.
   *
   * @method buildReport
   *
   ###
   buildReport: =>
      i = 0
      while i < @Questions.length
         @BuildMiniReport i
         i++
      @buildReportButtons()
      return

   ###*
   *
   * Adds the button(s) for the end report into the app container.
   *
   * @method buildReportButtons
   *
   ###
   buildReportButtons: =>
      GS_buttonSet = document.createElement('div')
      GS_buttonSet.id = 'GS_buttonSet'
      @_appContainer.appendChild GS_buttonSet
      GS_buttonSet.appendChild @_nextButton
      document.getElementById('GS_nextButton').lastChild.innerHTML = 'Continue'
      return

   ###*
   *
   * Checks if all of the submit buttons on the page have been pressed or not and determines whether the next button should be disabled.
   *
   * @method CheckAllSubmits
   *
   ###
   CheckAllSubmits: =>
      unsubmitted = 0
      i = 0
      while i < @_submitCheck.length
         if @_submitCheck[i] == false
            unsubmitted++
         i++
      if unsubmitted == 0
         document.getElementById('GS_nextButton').disabled = false
      else
         document.getElementById('GS_nextButton').disabled = true
      return

   ###*
   *
   * Takes the passed object data and embeds it according to it's type and whether it's feedback or pre/post activity content.
   *
   * @method EmbedMedia
   *
   * @param {String} type
   * @param {String} containerRef
   * @param {Object} mediaData
   *
   ###
   EmbedMedia: (type, containerRef, mediaData) =>
      mediaDomContent = undefined
      mediaDomLink = undefined
      validSrc = undefined
      mediaDomObj = document.createElement('div')
      mediaDomObj.setAttribute 'class', 'GS_Media'
      if type == 'feedback'
         $(mediaDomObj).addClass 'feedbackMedia'
      else if type == 'page'
         $(mediaDomObj).addClass 'pageMedia'
      switch mediaData.type
         when 'link'
            mediaDomContent = document.createElement('a')
            mediaDomContent.setAttribute 'class', 'GS_MediaLink'
            mediaDomContent.setAttribute 'href', mediaData.src
            mediaDomContent.setAttribute 'target', '_blank'
            if mediaData.description
               mediaDomContent.innerHTML = mediaData.description
            else
               mediaDomContent.innerHTML = 'Link'
            mediaDomObj.appendChild mediaDomContent
         when 'audio'
            mediaDomContent = document.createElement('audio')
            mediaDomContent.id = mediaData.id
            mediaDomContent.setAttribute 'class', 'GS_MediaAudio'
            mediaDomContent.setAttribute 'target', '_blank'
            mediaDomContent.innerHTML = '<source src="' + mediaData.mp3 + '" type="audio/mpeg">' + '<source src="' + mediaData.ogg + '" type="audio/ogg">' + '<source src="' + mediaData.wav + '" type="audio/wav"> Your browser does not support the audio tag.'
            mediaDomObj.appendChild mediaDomContent
            GS_audioButton = document.createElement('button')
            GS_audioButton.setAttribute 'class', 'GS_audioButton'
            GS_audioButton.setAttribute 'title', 'Play Audio Button'

            GS_audioButton.onclick = ->
               audioClip = document.getElementById(mediaData.id)
               audioClip.play()
               return

            mediaDomObj.appendChild GS_audioButton
         when 'image'
            if mediaData.mediaLink != 'none' and mediaData.mediaLink != null and mediaData.mediaLink != undefined and mediaData.mediaLink != ''
               mediaDomLink = document.createElement('a')
               mediaDomLink.setAttribute 'class', 'GS_MediaImageLink'
               mediaDomLink.setAttribute 'href', mediaData.mediaLink
               mediaDomLink.setAttribute 'target', '_blank'
            mediaDomContent = document.createElement('img')
            mediaDomContent.setAttribute 'class', 'GS_MediaImage embedMedia'
            mediaDomContent.setAttribute 'src', mediaData.src
            if mediaData.width != 'none'
               mediaDomContent.setAttribute 'width', mediaData.width
            else
               mediaDomContent.setAttribute 'width', '420'
            if mediaData.height != 'none'
               mediaDomContent.setAttribute 'height', mediaData.height
            else
               mediaDomContent.setAttribute 'height', '315'
            mediaDomObj.setAttribute 'style', 'text-align:center;'
            if mediaData.description
               mediaDomContent.setAttribute 'alt', mediaData.description

            mediaDomContent.onerror = ->
               mediaDomContent.setAttribute 'src', 'img/placeholder-error.png'
               mediaDomContent.setAttribute 'alt', 'Error. Image could not be loaded.'
               return

            mediaDomContent.onload = =>
               @HandleResizeEvent()

            if mediaData.mediaLink == 'none' or mediaData.mediaLink == null or mediaData.mediaLink == undefined or mediaData.mediaLink == ''
               mediaDomObj.appendChild mediaDomContent
            else
               mediaDomLink.appendChild mediaDomContent
               mediaDomObj.appendChild mediaDomLink
         when 'YouTubeVideo'
            #https://www.youtube.com/watch?v=OZBWfyYtYQY
            #<iframe width="420" height="315" src="https://www.youtube.com/embed/OZBWfyYtYQY" frameborder="0" allowfullscreen></iframe>
            validSrc = @validateYouTubeLink(mediaData.src)
            if validSrc
               mediaDomContent = document.createElement('iframe')
               mediaDomContent.setAttribute 'class', 'GS_MediaEmbeddedVideo embedMedia'
               mediaDomContent.setAttribute 'width', '420'
               mediaDomContent.setAttribute 'height', '315'
               mediaDomContent.setAttribute 'frameborder', '0'
               mediaDomContent.setAttribute 'allowfullscreen', 'true'
               mediaDomContent.setAttribute 'src', validSrc
               if type == 'page'
                  mediaDomObj.setAttribute 'style', 'text-align:center;'
               if mediaData.description
                  mediaDomContent.setAttribute 'alt', mediaData.description
               mediaDomObj.appendChild mediaDomContent
               mediaDomLink = document.createElement('a')
               mediaDomLink.setAttribute 'class', 'GS_MediaAltLink'
               mediaDomLink.setAttribute 'href', mediaData.altLink
               mediaDomLink.setAttribute 'target', '_blank'
               mediaDomLink.innerHTML = 'Alternate Link.'
               mediaDomObj.appendChild mediaDomLink
            else
               mediaDomContent = document.createElement('img')
               mediaDomContent.setAttribute 'class', 'GS_MediaImage embedMedia'
               mediaDomContent.setAttribute 'src', 'img/placeholder-error.png'
               mediaDomContent.setAttribute 'alt', 'Error. Video could not be loaded.'
               mediaDomContent.setAttribute 'width', '420'
               mediaDomContent.setAttribute 'width', '360'
               if type == 'page'
                  mediaDomObj.setAttribute 'style', 'text-align:center;'
               mediaDomObj.appendChild mediaDomContent
         when 'text'
            mediaDomContent = document.createElement('p')
            mediaDomContent.setAttribute 'class', 'GS_MediaText'
            mediaDomContent.setAttribute 'target', '_blank'
            mediaDomContent.innerHTML = mediaData.content
            mediaDomObj.appendChild mediaDomContent
         else
            break
      containerRef.appendChild mediaDomObj

      return

   ###*
   *
   * Takes the passed string and checks to see if it is a valid YouTube link.
   *
   * @method validateYouTubeLink
   *
   * @param {String} src
   *
   * @return {String} A valid Youtube link (if it validates).
   *
   ###
   validateYouTubeLink: (src) =>
      code = undefined
      if src.indexOf('www.youtube.com') != -1
         if src.indexOf('</iframe>') == -1
            if src.indexOf('watch?v=') != -1
               code = src.slice(src.indexOf('?v=') + 3)
               'https://www.youtube.com/embed/' + code
            else
               false
         else
            # they grabbed the embed code probably
            if src.indexOf('https://www.youtube.com/embed/') != -1
               src.slice src.indexOf('src') + 5, src.indexOf('"', src.indexOf('src') + 5)
            else
               false
      else
         false

   ###*
   *
   * Takes the passed array and shuffles it into a random order.
   *
   * @method shuffle
   *
   * @param {Array} o, array to shuffle
   *
   * @return {Array} Shuffled array
   *
   ###
   shuffle: (o) =>
      #v1.0
      j = undefined
      x = undefined
      i = o.length
      while i
         j = Math.floor(Math.random() * i)
         x = o[--i]
         o[i] = o[j]
         o[j] = x
      return o

   ###*
   *
   * Checks for all correct answers in GraphicSelectApp
   *
   * @method buildAnswerReferences
   *
   ###
   buildAnswerReferences: =>
      i = 0
      while i < @Questions.length
         @_questionCheck = []
         @_correctAnswers = []
         j = 0
         while j < @_appData.Answers.length
            correct = false
            if @Questions[i].answers[j].check == true
               correct = true
            @_questionCheck.push false
            @_correctAnswers.push correct
            j++
         @_allCheck.push @_questionCheck
         @_allCorrect.push @_correctAnswers
         i++
      return

   ###*
   *
   * Checks to see if browser is IE
   *
   * @method msieversion
   *
   * @return {Boolean} is IE
   *
   ###
   msieversion: =>
      ua = window.navigator.userAgent
      msie = ua.indexOf('MSIE ')
      if msie > 0 or ! !navigator.userAgent.match(/Trident.*rv\:11\./)
         true
      else
         false

   ###*
   * Generic Uyaan logging method. Used to try and prevent large amounts of console logging in production
   *
   * @method Uyaanog
   * @param {string} m
   * @return {} Console logs m
   ###
   Uyaanog: (m) ->
     if typeof UyaanDEBUG != 'undefined'
       if UyaanDEBUG
         console.log m
     return

   ###*
   *  
   * Another utility function, this one merges all the properties of object one into object two, with object one taking priority.
   *
   * @method mergeObjectData
   *
   * @param {Object} obj1 any JS object, this one will take priority, meaning if object 2 has a property of the same name 
   *                 or a property in this object, the property in object 2  it will be ignored.
   *
   * @param {Object} obj2 any JS object
   *
   * @return {Object} The resulting merged object.  
   *
   *###
   mergeObjectData: (obj1, obj2) =>
      obj3 = obj1

      if obj2.constructor is undefined or obj2.constructor is  null
         return obj3
      else if obj2.constructor is Object
         k = 0
         while k < Object.keys(obj2).length
            if obj3[Object.keys(obj2)[k]] is undefined
               obj3[Object.keys(obj2)[k]] = obj2[Object.keys(obj2)[k]]
            else if typeof obj3[Object.keys(obj2)[k]] is "object"
               @mergeObjectData(obj3[Object.keys(obj2)[k]], obj2[Object.keys(obj2)[k]])
            k++
      else
         return obj2
   
      return obj3

   ###*
   *  
   * Handle reszing for the LE
   *
   * @method mergeObjectData
   *
   *
   *###
   HandleResizeEvent: () =>
      try
         bnds = window.document.body.getBoundingClientRect()
         window.parent.document.getElementsByTagName("iframe")[0].style.height = (bnds.height + bnds.top + 20) + "px"
      catch
         @Uyaanog("resize error") 