(function(context, $) {

  "use strict";

  context.JK = context.JK || {};

  context.JK.CreateScheduledSession = function(app) {
    var gearUtils = context.JK.GearUtilsInstance;
    var sessionUtils = context.JK.SessionUtils;
    var logger = context.JK.logger;
    var rest = JK.Rest();
    var invitationDialog = null;
    var inviteMusiciansUtil = null;
    var instrumentSelector = null;
    var instrumentRSVP = null;
    var firstTimeShown = false;

    var MAX_GENRES = 1;
    var createSessionSettings = {
      createType: '<%= MusicSession::CREATE_TYPE_START_SCHEDULED %>',
      timezone: {},
      recurring_mode: {},
      language: {},
      band: {},
      musician_access: {},
      fans_access: {},
      open_rsvps: false,
      friends_can_join: false

    };
    var friendInput = null;

    // Main layout
    var $screen = $('#create-session-layout');
    var $wizardSteps = null;
    var $currentWizardStep = null;
    var step = 0;
    var $templateSteps = null;
    var $templateButtons = null;
    var $sessionButtons = null;
    var $startTimeList = null;
    var $endTimeList = null;
    var $timezoneList = null;
    var $recurringModeList = null;
    var $languageList = null;
    var $bandList = null;
    var $sessionPlusMusiciansLabel = null;
    var $editScheduledSessions = null;
    var $inputFiles = $screen.find('#session-select-files');
    var $btnSelectFiles = null;
    var $selectedFilenames = null;
    var $uploadSpinner = null;
    var $quickStartSoloBtn = null;
    var $quickStartFriendsBtn = null;
    var $quickStartOpenBtn = null;
    var $startOrScheduledBtn = null;
    var $featureSessions = null;

    // Step1 layout
    var $screenStep1 = null;
    var $createTypes = null;
    var $createTypeHelpers = null;
    var $scheduledSessions = null;
    var $fetchingSpinner = null;
    var $fetchingSpinnerLabel = null;
    var $noSessionFound = null;
    var $sessionHeader = null;
    var scheduledSessions = {};

    // Step4 layout
    var $policyTypes = null;

    var TOTAL_STEPS = 6;
    var STEP_HOME           = 0;
    var STEP_SELECT_TYPE    = 1;
    var STEP_SELECT_PLAYING = 2;
    var STEP_SELECT_INVITE  = 3;
    var STEP_SELECT_POLICY  = 4;
    var STEP_SELECT_CONFIRM = 5;

    var ONE_HOUR = 3600 * 1000;
    var ONE_MINUTE = 60 * 1000;
    var ONE_DAY = ONE_HOUR * 24;

    var defaultTimeArray = ["12:00 AM", "12:30 AM", "01:00 AM", "01:30 AM", "02:00 AM", "02:30 AM",
      "03:00 AM", "03:30 AM", "04:00 AM", "04:30 AM", "05:00 AM", "05:30 AM", "06:00 AM", "06:30 AM",
      "07:00 AM", "07:30 AM", "08:00 AM", "08:30 AM", "09:00 AM", "09:30 AM", "10:00 AM", "10:30 AM",
      "11:00 AM", "11:30 AM", "12:00 PM", "12:30 PM", "01:00 PM", "01:30 PM", "02:00 PM", "02:30 PM",
      "03:00 PM", "03:30 PM", "04:00 PM", "04:30 PM", "05:00 PM", "05:30 PM", "06:00 PM", "06:30 PM",
      "07:00 PM", "07:30 PM", "08:00 PM", "08:30 PM", "09:00 PM", "09:30 PM", "10:00 PM", "10:30 PM",
      "11:00 PM", "11:30 PM"];

    var proficiencyDescriptionMap = {
      "0": "Any",
      "1": "Beg",
      "2": "Beg/Int",
      "3": "Int",
      "4": "Int/Adv",
      "5": "Adv"
    };

    function afterLoadScheduledSessions(sessionList) {

      $featureSessions.empty()

      createSessionSettings.session_count = sessionList.length;

      if (createSessionSettings.session_count == 0) {
        createSessionSettings.selectedSessionId = null;
        $featureSessions.append('<tr><td colspan="4">No sessions</td></tr>')
      }
      else {
        $.each(sessionList, function (i, session) {
          scheduledSessions[session.id] = session;
        });

        context._.each(sessionList, function (session) {
          session.scheduled_start = new Date(session.scheduled_start).toDateString() + ', ' +
              context.JK.formatUtcTime(new Date(session.scheduled_start), false);

          var time = session.pretty_scheduled_start_with_timezone;
          var receivedUsers = {}
          var sessionLink = '/client#/account/sessionDetail/' + session.id
          var isActive = session.active_music_session && session.active_music_session.participants.length > 0

          if(isActive) {
            time = 'NOW'

            context._.each(session.active_music_session.participants, function(participant) {
              receivedUsers[participant.id] = participant.name;
            })

            sessionLink = '/sessions/' + session.id
          }
          else {

            context._.each(session.approved_rsvps, function(approved_rsvp) {
              receivedUsers[approved_rsvp.id] = approved_rsvp.name;
            })

            context._.each(session.invitations, function(invitation) {
              receivedUsers[invitation.receiver_id] = invitation.receiver_name;
            })
          }
          var $row = $('<tr><td class="session-link"></td><td class="session-users"></td><td>' + session.pretty_scheduled_start_short + '</td><td class="actions"></td></tr>')
          var $sessionCell = $row.find('.session-link')
          if (isActive) {
            var $sessionLink = $('<a href="' + sessionLink + '" style="color:#fc0" rel="external">' + session.name + '</a>')
            $sessionCell.append($sessionLink)
            context.JK.popExternalLinks($sessionCell)
          }
          else
          {
            var $sessionLink = $('<a href="' + sessionLink + '" style="color:#fc0">' + session.name + '</a>')
            $sessionCell.append($sessionLink)
          }

          var $actionsCell = $row.find('.actions');
          var $actionsLink = $('<a href="/client#/session/' + session.id + '" style="color:#fc0">join</a>')
          $actionsCell.append($actionsLink)

          var msg = '';
          context._.each(receivedUsers, function(value, key) {
            var url = '/client#/profile/' + key
            msg += '<a href="' + url +'">' + value + '</a>, '
          })

          if (msg.length > 0) {
            msg = msg.slice(0, -2)
          }
          var $usersCell = $row.find('.session-users')
          $usersCell.append(msg)

          $featureSessions.append($row);
        });
      }
    }


    function afterLoadScheduledSessions2(sessionList) {

      createSessionSettings.session_count = sessionList.length;

      if (createSessionSettings.session_count == 0) {
        $noSessionFound.show();
        createSessionSettings.selectedSessionId = null;
      }
      else {
        $noSessionFound.hide();
        $.each(sessionList, function (i, session) {
          scheduledSessions[session.id] = session;
        });

        context._.each(sessionList, function (session) {
          session.scheduled_start = new Date(session.scheduled_start).toDateString() + ', ' +
            context.JK.formatUtcTime(new Date(session.scheduled_start), false);

          var options = {
            id: session.id,
            name: session.name,
            scheduled_start: session.pretty_scheduled_start_short
          };
          var txt = $(context._.template($('#template-scheduled-session').html(), options, { variable: 'data' }));
          $scheduledSessions.append(txt);
        });

        var firstSession = function() {
          var $firstSession = $scheduledSessions.children().first().find('input[name="scheduled-session-info"]');
          $firstSession.attr('checked', 'checked');
          createSessionSettings.selectedSessionId = $firstSession.attr('data-session-id');

        };
        if (createSessionSettings.selectedSessionId == null) {
          firstSession();
        }
        else {
          var $selectedSession = $scheduledSessions.children().first().find('input[name="scheduled-session-info"][data-session-id="' + createSessionSettings.selectedSessionId + '"]');
          if ($selectedSession.length)
            $selectedSession.attr('checked', 'checked');
          else
            firstSession();
        }


        $scheduledSessions.iCheck({
          checkboxClass: 'icheckbox_minimal',
          radioClass: 'iradio_minimal',
          inheritClass: true
        });
      }

      if (createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_START_SCHEDULED%>' && createSessionSettings.session_count == 0)
        $editScheduledSessions.hide();
      else if (createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_START_SCHEDULED%>' && createSessionSettings.session_count > 0)
        $editScheduledSessions.show();

      var $btnNext = $screen.find('.btn-next');

      if (step == STEP_SELECT_TYPE && createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_START_SCHEDULED%>' && createSessionSettings.selectedSessionId == null) {
        $btnNext.addClass('disabled');
      }
      else {
        $btnNext.removeClass('disabled');
      }
    }

    function clickQuickStartSolo () {

      logger.debug("user clicked quick start solo")
      createSessionSettings.createType = '<%= MusicSession::CREATE_TYPE_QUICK_START %>'
      createSessionSettings.friends_can_join = false
      next();
      return false;
    }

    function clickQuickStartFriends () {

      logger.debug("user clicked quick start solo")
      createSessionSettings.createType = '<%= MusicSession::CREATE_TYPE_QUICK_START %>'
      createSessionSettings.friends_can_join = true
      next();
      return false;
    }

    function clickQuickStartPublic () {

      logger.debug("user clicked quick start public")
      createSessionSettings.createType = '<%= MusicSession::CREATE_TYPE_QUICK_PUBLIC %>'
      createSessionSettings.friends_can_join = false
      next();
      return false;
    }

    function clickStartOrSchedule () {

      logger.debug("user clicked start or scheduled")
      toggleCreateType(null, '<%= MusicSession::CREATE_TYPE_IMMEDIATE %>')
      next();
      return false;
    }

    function afterLoadUserDetail(userDetail) {
      var userInstruments = [];
      $.each(userDetail.instruments, function(index, userInstrument) {
        userInstrument.level = userInstrument.proficiency_level;
        userInstruments.push(userInstrument);
      })

      instrumentSelector.render('#instrument-select-list', userInstruments);
      instrumentRSVP.render('#instrument-select-rsvp-list');

      $("#instrument-select-list").iCheck({
        checkboxClass: 'icheckbox_minimal',
        radioClass: 'iradio_minimal',
        inheritClass: true
      });

      $("#instrument-select-rsvp-list").iCheck({
        checkboxClass: 'icheckbox_minimal',
        radioClass: 'iradio_minimal',
        inheritClass: true
      });
    }

    function beforeShowStep0() {
      $scheduledSessions.empty();
      $noSessionFound.hide();
      $fetchingSpinner.show();
      $fetchingSpinnerLabel.show();

      rest.findScheduledSessions({})
          .done(afterLoadScheduledSessions)
          .fail(app.ajaxError)
          .always(function(response) {
            $fetchingSpinner.hide();
            $fetchingSpinnerLabel.hide();
          });

      rest.getUserDetail()
          .done(afterLoadUserDetail)
          .fail(app.ajaxError);


    }


    function beforeShowStep1() {
      $scheduledSessions.empty();
      $noSessionFound.hide();
      $fetchingSpinner.show();
      $fetchingSpinnerLabel.show();

      createSessionSettings.startDate = createSessionSettings.startDate || (new Date().toDateString());

      $screen.find("#session-start-date").val(createSessionSettings.startDate);
      toggleDate(true);
      toggleStartTime();
      toggleStepStatus();
      sessionUtils.defaultTimezone($timezoneList);
      if(firstTimeShown) {
        firstTimeShown = false;
        $screen.find('#session-when-start-scheduled').iCheck('check');
      }
    }

    function beforeShowStep2() {
    }

    function beforeShowStep3() {
      rest.getBands(context.JK.currentUserId)
        .done(function(result) {
          var options = $screen.find("#session-band-list");
          options.empty();
          options.append($("<option />").val('').text('No'));
          $.each(result, function(idx, item) {
            options.append($("<option />").attr('value',item.id).text(item.name));
          });
          context.JK.dropdown($bandList);
        })
        .fail(app.ajaxError)
    }

    function beforeShowStep4() {
    }

    function beforeShowStep5() {
      var startType = null;
      if (willOptionStartSession()) {
        startType = 'Now!';
        createSessionSettings.startType = "START SESSION";
      }
      else if (createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_RSVP %>') {
        startType = 'To be determined after RSVPs received';
        createSessionSettings.startType = "PUBLISH SESSION";
      }
      else if (createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_SCHEDULE_FUTURE %>') {
        startType = createSessionSettings.startDate + ',' +
                    createSessionSettings.startTime + ', ' +
                    createSessionSettings.timezone.label;
        createSessionSettings.startType = "PUBLISH SESSION";
      }
      $('#session-step-5 #session-start-type-disp').html(startType);

      var sessionName = createSessionSettings.name;
      sessionName += ' (' + createSessionSettings.genresValues[0] + ')';
      $screen.find('#session-name-disp').html(sessionName);

      var sessionDescription = createSessionSettings.description;
      $screen.find('#session-description-disp').html(sessionDescription);

      var sessionNotations = [];
      for (var i = 0; i < createSessionSettings.notations.length; i++) {
        var name = createSessionSettings.notations[i].file_name;
        sessionNotations.push(name);
      }
      if(sessionNotations.length > 0) {
        $screen.find('#session-notations-disp').html("Notations: " + sessionNotations.join(', '));
      }
      else {
        $screen.find('#session-notations-disp').html('');
      }

      $screen.find('#session-language-disp').html(createSessionSettings.language.label);
      $screen.find('#session-band-disp').html(createSessionSettings.band.label);

      var plusMusicians = $screen.find('#session-plus-musicians')[0].checked;

      var sessionInvited = [];
      var invitedFriends = inviteMusiciansUtil.getInvitedFriendNames();
      $.each(invitedFriends, function(index, friend) {
        sessionInvited.push(friend);
      });

      var sessionInvitedString = sessionInvited.join(', ');
      if (createSessionSettings.musician_access.value == 'musicians-approval') {
        if (plusMusicians) {
          if (invitedFriends.length == 0)
            sessionInvitedString = "Any interested JamKazam musicians that I approve";
          else
            sessionInvitedString += ", plus any interested JamKazam musicians that I approve";
        }
        else {
          if (invitedFriends.length == 0) {
            sessionInvitedString = "No open RSVPs";
          }
          else {
            sessionInvitedString += " (No open RSVPs)";
          }
        }
      }
      else if (createSessionSettings.musician_access.value == 'musicians') {
        if (invitedFriends.length == 0)
          sessionInvitedString = "Any interested JamKazam musicians who want to join us";
        else
          sessionInvitedString += ", plus any interested JamKazam musicians who want to join us";
      }
      $screen.find('#session-invited-disp').html(sessionInvitedString);

      if (createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_START_SCHEDULED%>') {
        var session = scheduledSessions[createSessionSettings.selectedSessionId];
        if (session.approved_rsvps.length > 0) {
          var instruments_me = [];
          $.each(session.approved_rsvps, function(index, user) {
            if (user.id == context.JK.currentUserId) {
              $.each(user.instrument_list, function(index, instrument) {
                instruments_me.push(instrument.desc ? instrument.desc : 'Any Instrument');
              });
            }
          });
          $screen.find('#session-instruments-me-disp').html(instruments_me.join(', '));
        }

        if (session.open_slots.length > 0) {
          var instruments_rsvp = {};
          $.each(session.open_slots, function(index, slot) {
            if (instruments_rsvp[slot.description]) {
              instruments_rsvp[slot.description]["count"] = instruments_rsvp[slot.description]["count"] + 1;
            }
            else {
              instruments_rsvp[slot.description] = {"count": 1, "level": slot.proficiency_desc};
            }
          });

          var instruments_rsvp_arr = $.makeArray(instruments_rsvp);
          var instruments_str_arr = [];
          $.map(instruments_rsvp_arr, function(val, i) {
            instruments_str_arr.push(i + ' (' + val.count + ') (' + val.level + ')');
          })
          $screen.find('#session-instruments-rsvp-disp').html(instruments_str_arr.join(', '));
        }
      }
      else {
        var instruments_me = [];
        $.each(getCreatorInstruments(), function(index, instrument) {
          instruments_me.push(instrument.name);
        });
        $screen.find('#session-instruments-me-disp').html(instruments_me.join(', '));

        var instruments_rsvp = [];
        var otherInstruments = instrumentRSVP.getSelectedInstruments();
        var isUnstructuredRsvp = otherInstruments.length == 0 && userSelectedSlots(createSessionSettings.createType);
        if(isUnstructuredRsvp) {
          instruments_rsvp.push('Any Instrument Allowed');
        }
        $.each(otherInstruments, function(index, instrument) {
          instruments_rsvp.push(instrument.name + ' (' + instrument.count + ') (' + proficiencyDescriptionMap[instrument.level] + ')');
        });
        $screen.find('#session-instruments-rsvp-disp').html(instruments_rsvp.join(', '));
      }

      $screen.find('#session-musician-access-disp').html('Musicians: ' + createSessionSettings.musician_access.label);
      $screen.find('#session-fans-access-disp').html('Fans: ' + createSessionSettings.fans_access.label);

      $screen.find('#session-policy-disp').html(createSessionSettings.session_policy);
    }

    function beforeMoveStep0() {
      return true;
    }

    function beforeMoveStep1() {
      if (createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_START_SCHEDULED%>') {
        createSessionSettings.selectedSessionId = $scheduledSessions.find('.iradio_minimal.checked input[name="scheduled-session-info"]').attr('data-session-id');
        var session = scheduledSessions[createSessionSettings.selectedSessionId];

        if(session == null) {
          // TODO: notify user they need to pick session? Or maybe it should be grayed out.
          return false;
        }
        var moveToFinish = function() {
          app.layout.closeDialog('confirm');
          createSessionSettings.startDate = new Date(session.scheduled_start).toDateString();
          createSessionSettings.startTime = context.JK.formatUtcTime(new Date(session.scheduled_start), false);
          createSessionSettings.genresValues = session.genres;
          createSessionSettings.genres = [session.genre_id];
          createSessionSettings.timezone.label = session.timezone_description;
          createSessionSettings.timezone.value = session.timezone;
          createSessionSettings.name = session.name;
          createSessionSettings.description = session.description;
          createSessionSettings.notations = session.music_notations;
          createSessionSettings.language.label = session.language_description;
          createSessionSettings.language.value = session.language;
          createSessionSettings.session_policy = session.legal_policy;
          createSessionSettings.musician_access.label = session.musician_access_description;
          createSessionSettings.fans_access.label = session.fan_access_description;
          createSessionSettings.recurring_mode.value = session.recurring_mode;
          createSessionSettings.open_rsvps = session.open_rsvps;

          step = STEP_SELECT_CONFIRM;
          moveToStep();
        }

        var currentTime = new Date();
        var startTime = new Date(session.scheduled_start);
        var diffTime = startTime.getTime() - currentTime.getTime();
        if (diffTime > ONE_HOUR) {
          var confirmDialog = new context.JK.ConfirmDialog(app, "START SESSION NOW",
          "You are starting a session that is scheduled to begin more than one hour from now. Are you sure you want to do this?",
          "Future Session", moveToFinish);
          confirmDialog.initialize();
          context.JK.app.layout.showDialog('confirm');
        }
        else {
          moveToFinish();
        }
        return false;
      }
      else if (createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_QUICK_START %>') {
        createSessionSettings.genresValues = ['Pop'];
        createSessionSettings.genres = ['pop'];
        createSessionSettings.timezone.label = "(GMT-06:00) Central Time (US & Canada)";
        createSessionSettings.timezone.value = "Central Time (US & Canada),America/Chicago";
        createSessionSettings.name = "Private Test Session";
        createSessionSettings.description = "Private session set up just to test things out in the session interface by myself.";
        createSessionSettings.notations = [];
        createSessionSettings.language.label = 'English';
        createSessionSettings.language.value = 'eng';
        createSessionSettings.session_policy = 'Standard';
        createSessionSettings.musician_access.label = "Only RSVP musicians may join";
        createSessionSettings.musician_access.value = "only-rsvp";
        createSessionSettings.fans_access.label = "Fans may not listen to session";
        createSessionSettings.fans_access.value = "no-listen-chat";
        createSessionSettings.recurring_mode.label = 'Not Recurring';
        createSessionSettings.recurring_mode.value = 'once';
      }
      else if (createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_QUICK_PUBLIC %>') {
        createSessionSettings.genresValues = ['Pop'];
        createSessionSettings.genres = ['pop'];
        createSessionSettings.timezone.label = "(GMT-06:00) Central Time (US & Canada)";
        createSessionSettings.timezone.value = "Central Time (US & Canada),America/Chicago";
        createSessionSettings.name = "Open Session";
        createSessionSettings.description = "Feel free to join this session, it's open!";
        createSessionSettings.notations = [];
        createSessionSettings.language.label = 'English';
        createSessionSettings.language.value = 'eng';
        createSessionSettings.session_policy = 'Standard';
        createSessionSettings.musician_access.label = "Musicians may join at will";
        createSessionSettings.musician_access.value = "musicians";
        createSessionSettings.fans_access.label = "Fans can listen to you while you're playing in session, and can text chat with each other while listening.";
        createSessionSettings.fans_access.value = "listen-chat-each";
        createSessionSettings.recurring_mode.label = 'Not Recurring';
        createSessionSettings.recurring_mode.value = 'once';
      }
      else {
        createSessionSettings.startDate = $screen.find('#session-start-date').val();
        createSessionSettings.startTime = $startTimeList.val();
        createSessionSettings.endTime = $endTimeList.val();
        createSessionSettings.notations = [];
        createSessionSettings.selectedSessionId = $scheduledSessions.find('.iradio_minimal.checked input[name="scheduled-session-info"]').attr('data-session-id');
        createSessionSettings.timezone.value = $timezoneList.val();
        createSessionSettings.timezone.label = $timezoneList.get(0).options[$timezoneList.get(0).selectedIndex].text;
        createSessionSettings.recurring_mode.label = $recurringModeList.get(0).options[$recurringModeList.get(0).selectedIndex].text;
        createSessionSettings.recurring_mode.value = $recurringModeList.val();
        createSessionSettings.open_rsvps = $screen.find('#session-plus-musicians')[0].checked;
      }

      return true;
    }

    function uploadNotations(notations) {
      var formData = new FormData();
      var maxExceeded = false;
      $.each(notations, function(i, file) {
        var max =  10 * 1024 * 1024;
        if(file.size > max) {
          maxExceeded = true;
          return false;
        }
        formData.append('files[]', file);
      });

      if(maxExceeded) {
        app.notify(
          { title: "Maximum Music Notation Size Exceeded",
            text: "You can only upload files up to 10 megabytes in size."
          });
        var deferred = new $.Deferred();
        deferred.reject();
        return deferred;
      }

      formData.append('attachment_type', 'notation')
      formData.append('client_id', app.clientId);
      $btnSelectFiles.text('UPLOADING...').data('uploading', true)
      $uploadSpinner.show();
      return rest.uploadMusicNotations(formData)
        .done(function(response) {
          var error_files = [];
          $.each(response, function(i, music_notation) {
            if (music_notation.errors) {
              error_files.push(createSessionSettings.notations[i].name);
            }
          })
          if (error_files.length > 0) {
            app.notifyAlert("Failed to upload notations.", error_files.join(', '));
          }

          createSessionSettings.notations = $.merge(createSessionSettings.notations, response);
        })
        .fail(function(jqXHR) {
          if(jqXHR.status == 413) {
            // the file is too big.   Let the user know.
            // This should happen when they select the file, but a misconfiguration on the server could cause this.
            app.notify(
              { title: "Maximum Music Notation Size Exceeded",
                text: "You can only upload files up to 10 megabytes in size."
              })
          }
          else {
            app.notifyServerError(jqXHR, "Unable to upload music notations");
          }
        })
        .always(function() {
          $btnSelectFiles.text('SELECT FILES...').data('uploading', null)
          $uploadSpinner.hide();
        })
    }

    function beforeMoveStep2() {
      var isValid = true;
      var name = $screen.find('#session-name').val();
      if (!name) {
        $('#divSessionName .error-text').remove();
        $('#divSessionName').addClass("error");
        $screen.find('#session-name').after("<ul class='error-text'><li>Name is required</li></ul>");
        isValid = false;
      }
      else {
        $('#divSessionName').removeClass("error");
      }

      var description = $screen.find('#session-description').val();
      if (!description) {
        $('#divSessionDescription .error-text').remove();
        $('#divSessionDescription').addClass("error");
        $screen.find('#session-description').after("<ul class='error-text'><li>Description is required</li></ul>");
        isValid = false;
      }
      else {
        $('#divSessionDescription').removeClass("error");
      }

      var genres = context.JK.GenreSelectorHelper.getSelectedGenres('#create-session-genre');
      var genresValues = context.JK.GenreSelectorHelper.getSelectedGenresValues('#create-session-genre');

      if (genres.length === 0) {
        $('#divSessionGenre .error-text').remove();
        $('#divSessionGenre').addClass("error");
        $('#create-session-genre').after("<ul class='error-text'><li>You must select a genre.</li></ul>");
        isValid = false;
      }
      else {
        $('#divSessionGenre').removeClass("error");
      }

      if (isValid) {
        createSessionSettings.genres = genres;
        createSessionSettings.genresValues = genresValues;
        createSessionSettings.name = name;
        createSessionSettings.description = description;
      }

      return isValid;
    }

    function beforeMoveStep3() {
      createSessionSettings.language.value = $languageList.val();
      createSessionSettings.language.label = $languageList.get(0).options[$languageList.get(0).selectedIndex].text;

      createSessionSettings.band.value = $bandList.val();
      if (createSessionSettings.band.value === '0')
        createSessionSettings.band.label = '';
      else
        createSessionSettings.band.label = $bandList.get(0).options[$bandList.get(0).selectedIndex].text;

      createSessionSettings.open_rsvps = $screen.find('#session-plus-musicians')[0].checked;
      return true;
    }

    function beforeMoveStep4() {
      var isValid = true;
      var sessionPolicyChecked = $screen.find('#session-policy-confirm').is(':checked');
      if (!sessionPolicyChecked) {
        $('#divSessionPolicy .error-text').remove();
        $('#divSessionPolicy').addClass("error");
        $('#divSessionPolicyHelper').after("<ul class='error-text'><li>You must accept the Session Policy.</li></ul>");
        isValid = false;
      }
      else {
        $('#divSessionPolicy').removeClass("error");
      }

      createSessionSettings.session_policy = $('input[name="session-policy-type"][checked="checked"]').attr('policy-id');
      var $musicianAccess = $screen.find('#session-musician-access');
      createSessionSettings.musician_access.value = $musicianAccess.val();
      createSessionSettings.musician_access.label = $musicianAccess.get(0).options[$musicianAccess.get(0).selectedIndex].text;

      var $fansAccess = $screen.find('#session-fans-access');
      createSessionSettings.fans_access.value = $fansAccess.val();
      createSessionSettings.fans_access.label = $fansAccess.get(0).options[$fansAccess.get(0).selectedIndex].text;

      var $friendsCanJoin = $screen.find('#session-friends-can-join');
      createSessionSettings.friends_can_join = $friendsCanJoin.val() == 'true'
      //createSessionSettings.friends_can_join.label = $friendsCanJoin.get(0).options[$friendsCanJoin.get(0).selectedIndex].text;

      return isValid;
    }

    function beforeMoveStep5() {
    }

    function startSessionClicked() {
      var $btn = $(this);
      if($btn.is('.disabled')) { return false; }
      $btn.addClass('disabled');

      if(willOptionStartSession()) {

        var shouldVerifyNetwork = createSessionSettings.musician_access.value != 'only-rsvp';

        gearUtils.guardAgainstInvalidConfiguration(app, shouldVerifyNetwork)
          .fail(function() {
            $btn.removeClass('disabled')
            app.notify(
              { title: "Unable to Start New Session",
                text: "You can only start a session once you have working audio gear and a tested internet connection."
              })
          })
          .done(function(){
            startSession($btn);
          });
      }
      else {
        startSession($btn);
      }

      return false;
    }

    // did the user have to pick the RSVP slots explicitely?
    function userSelectedSlots(createType) {
      return createType == "immediately" || createType == "schedule-future" || createType == "rsvp";
    }

    function startSession($startBtn) {

      var data = {};

      if (createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_START_SCHEDULED%>') {
        data = scheduledSessions[createSessionSettings.selectedSessionId];
      }
      else {
        data.name = createSessionSettings.name;
        data.description = createSessionSettings.description;
        data.genres = createSessionSettings.genres;
        if (createSessionSettings.musician_access.value == 'only-rsvp') {
          data.musician_access = false;
          data.approval_required = false;
        }
        else if (createSessionSettings.musician_access.value == 'musicians-approval') {
          data.musician_access = true;
          data.approval_required = true;
        }
        else if (createSessionSettings.musician_access.value == 'musicians') {
          data.musician_access = true;
          data.approval_required = false;
        }

        if (createSessionSettings.fans_access.value == 'no-listen-chat') {
          data.fan_access = false; data.fan_chat = false;
        }
        else if (createSessionSettings.fans_access.value == 'listen-chat-each') {
          data.fan_access = true; data.fan_chat = false;
        }
        else if (createSessionSettings.fans_access.value == 'listen-chat-band') {
          data.fan_access = true; data.fan_chat = true;
        }
        data.legal_policy = createSessionSettings.session_policy;
        data.legal_terms = true;
        data.language = createSessionSettings.language.value;
        data.band = createSessionSettings.band.value;
        if (createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_QUICK_START %>' || createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_IMMEDIATE %>' || createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_QUICK_PUBLIC %>') {
          data.start = new Date().toDateString() + ' ' + context.JK.formatUtcTime(new Date(), false);
          data.duration = "60";
        }
        else if (createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_RSVP %>') {
          data.start = ""; data.duration = "0";
        }
        else {
          data.start = createSessionSettings.startDate + ' ' + createSessionSettings.startTime;
          var startIndex = defaultTimeArray.indexOf(createSessionSettings.startTime);
          var endIndex = defaultTimeArray.indexOf(createSessionSettings.endTime);
          if (endIndex > startIndex) {
            data.duration = (endIndex - startIndex) * 30;
          }
          else {
            data.duration = (endIndex + defaultTimeArray.length - startIndex + 1) * 30;
          }

//          console.log(data.duration);
//          var endDate = new Date(createSessionSettings.startDate + ' ' + createSessionSettings.endTime);
//          data.duration = (endDate - new Date(data.start)) / ONE_MINUTE;
//          if (createSessionSettings.endTime == defaultTimeArray[0]) {
//            data.duration += ONE_DAY / ONE_MINUTE;
//          }
        }
        data.invitations = inviteMusiciansUtil.getInvitedFriends();
        data.recurring_mode = createSessionSettings.recurring_mode.value;
        data.music_notations = createSessionSettings.notations;
        data.timezone = createSessionSettings.timezone.value;
        data.open_rsvps = createSessionSettings.open_rsvps;
        data.create_type = createSessionSettings.createType;
        data.friends_can_join = createSessionSettings.friends_can_join;

        data.rsvp_slots = [];
        $.each(getCreatorInstruments(), function(index, instrument) {
          var slot = {};
          slot.instrument_id = instrument.id;
          slot.proficiency_level = instrument.level;
          slot.approve = true;
          data.rsvp_slots.push(slot);
        });

        var otherInstruments = instrumentRSVP.getSelectedInstruments();
        data.isUnstructuredRsvp = otherInstruments.length == 0 && userSelectedSlots(createSessionSettings.createType);
        $.each(instrumentRSVP.getSelectedInstruments(), function(index, instrument) {
          for (var i = 0; i < instrument.count; i++) {
            var slot = {};
            slot.instrument_id = instrument.id;
            slot.proficiency_level = instrument.level;
            slot.approve = false;
            data.rsvp_slots.push(slot);
          }
        });
      }

      var joinSession = function(sessionId) {
        var invitationCount = data.invitations.length;
        context.JK.GA.trackSessionCount(data.musician_access, data.fan_access, invitationCount);

        // we redirect to the session screen, which handles the REST call to POST /participants.
        logger.debug("joining session screen: " + sessionId)
        context.location = '/client#/session/' + sessionId;
      };

      if (createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_START_SCHEDULED%>') {

        // warn user if it's a TBD session
        if (data.scheduled_start_date === "") {
          sessionUtils.tbdScheduledSessionWarning(
            function(evt) {
              context.JK.app.layout.closeDialog('alert');
              joinSession(createSessionSettings.selectedSessionId);
              $('#create-session-buttons .btn-next').off('click');
            });
            var $btnNext = $screen.find('.btn-next');
            $btnNext.removeClass('disabled');
        }
        else {
          joinSession(createSessionSettings.selectedSessionId);
          $('#create-session-buttons .btn-next').off('click');
        }
      }
      else {
        rest.createScheduledSession(data)
          .done(function(response) {
            logger.debug("created session on server");
            $('#create-session-buttons .btn-next').off('click');
            var newSessionId = response.id;

            if (createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_QUICK_START %>' || createSessionSettings.createType == "immediately" || createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_QUICK_PUBLIC %>') {
              joinSession(newSessionId);
            }
            else {
              app.notifyAlert("Session published! It can be now found on the Find Session screen.");
              context.location = '/client#/home';
            }
          })
          .fail(function(jqXHR){
            $startBtn.removeClass('disabled');
            logger.debug("unable to schedule a session")
            app.notifyServerError(jqXHR, "Unable to schedule a session");
          })
      }
    }

    var STEPS = {
      0: {
        beforeShow: beforeShowStep0,
        beforeMove: beforeMoveStep0
      },
      1: {
        beforeShow: beforeShowStep1,
        beforeMove: beforeMoveStep1
      },
      2: {
        beforeShow: beforeShowStep2,
        beforeMove: beforeMoveStep2
      },
      3: {
        beforeShow: beforeShowStep3,
        beforeMove: beforeMoveStep3
      },
      4: {
        beforeShow: beforeShowStep4,
        beforeMove: beforeMoveStep4
      },
      5: {
        beforeShow: beforeShowStep5,
        beforeMove: beforeMoveStep5
      }
    };

    function moveToStep() {
      var $nextWizardStep = $wizardSteps.filter($('[layout-wizard-step=' + step + ']'));

      $wizardSteps.hide();

      $currentWizardStep = $nextWizardStep;

      $currentWizardStep.show();

      var $sessionSteps = $(context._.template($templateSteps.html(), { variable: 'data' }));
      var $activeStep = $sessionSteps.find('.session-stepnumber[data-step-number="' + step + '"]');
      $activeStep.addClass('session-stepactive');
      $activeStep.next().show();
      var $createSessionSteps = $("<div id='create-session-steps'><div id='passed-steps' class='left'></div><div id='todo-steps' class='right'></div><div class='clearall'></div></div></div>");
      for (var i = 0; i < TOTAL_STEPS; i++) {
        var $eachStep = $sessionSteps.find('.session-stepnumber[data-step-number="' + i + '"]');

        if (createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_START_SCHEDULED%>') {
          if (step == STEP_SELECT_TYPE) {
            if (createSessionSettings.session_count > 0 && i == STEP_SELECT_CONFIRM) {
              $eachStep.on('click', next);
              $eachStep.addClass('session-stephover');
            }
          }
          else if (step == STEP_SELECT_CONFIRM && i == STEP_SELECT_TYPE) {
            $eachStep.on('click', back);
            $eachStep.addClass('session-stephover');
          }
        }
        else if (createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_QUICK_START %>') {
          if (step == STEP_SELECT_CONFIRM && i == STEP_SELECT_TYPE) {
            $eachStep.on('click', back);
            $eachStep.addClass('session-stephover');
          }
          else if (step == STEP_SELECT_TYPE && i == STEP_SELECT_CONFIRM) {
            $eachStep.on('click', next);
            $eachStep.addClass('session-stephover');
          }
        }
        else {
          if (i == step - 1) {
            $eachStep.on('click', back);
            $eachStep.addClass('session-stephover');
          }
          else if (i == step + 1) {
            $eachStep.on('click', next);
            $eachStep.addClass('session-stephover');
          }
        }

        if (i <= step) {
          $createSessionSteps.find("#passed-steps").append($eachStep.clone(true, true));
          $createSessionSteps.find("#passed-steps").append($eachStep.next().clone());
        }
        else {
          $createSessionSteps.find("#todo-steps").append($eachStep.clone(true, true));
          $createSessionSteps.find("#todo-steps").append($eachStep.next().clone());
        }
      }
      $createSessionSteps.find("#passed-steps").append($("<div class='clearall'></div>"));
      $createSessionSteps.find("#todo-steps").append($("<div class='clearall'></div>"));
      $screen.find('#create-session-steps').replaceWith($createSessionSteps);

      if (step == 0) {
        $sessionHeader.hide()
      }
      else {
        $sessionHeader.show()
      }
      beforeShowStep();

      // update buttons
      var $sessionButtonsContent = $(context._.template($templateButtons.html(), {}, {variable: 'data'}));

      var $btnBack = $sessionButtonsContent.find('.btn-back');
      var $btnNext = $sessionButtonsContent.find('.btn-next');
      var $btnCancel = $sessionButtonsContent.find('.btn-cancel');

      // hide back button if 1st step or last step
      if (step == 0) {
        $btnBack.hide();
        $btnNext.hide();
      }
      else {
        $btnNext.show();
      }

      if (step == STEP_SELECT_TYPE && createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_START_SCHEDULED%>' && createSessionSettings.selectedSessionId == null) {
        $btnNext.addClass('disabled');
      }
      else {
        $btnNext.removeClass('disabled');
      }

      if (step == STEP_SELECT_CONFIRM) {
        $btnNext.html(createSessionSettings.startType);
        $btnNext.on('click', startSessionClicked);
      }
      else
        $btnNext.on('click', next);

      $btnBack.on('click', back);

      $sessionButtons.empty();
      $sessionButtons.append($sessionButtonsContent);
    }

    function back(event) {
      if (event) {
        event.preventDefault();
      }

      if ($(this).is('.disabled')) return false;
      if ($.inArray(createSessionSettings.createType, ['<%= MusicSession::CREATE_TYPE_START_SCHEDULED%>', '<%= MusicSession::CREATE_TYPE_QUICK_START %>']) > -1)
        step = STEP_SELECT_TYPE;
      else
        step--;
      moveToStep();
      return false;
    }

    function onEditSessions(event) {
      window.location = "/client#/account/sessions"
      return false;
    }

    // will this option result in a session being started?
    function willOptionStartSession() {
      return createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_START_SCHEDULED%>' ||
             createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_IMMEDIATE %>' ||
             createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_QUICK_START %>' ||
             createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_QUICK_PUBLIC%>';
    }

    function optionRequiresMultiplayerProfile() {
      return createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_START_SCHEDULED%>' ||
          createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_IMMEDIATE %>' ||
          createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_RSVP %>' ||
          createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_SCHEDULE_FUTURE %>' ||
          createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_QUICK_PUBLIC %>';
    }

    function next(event) {
      if(willOptionStartSession()) {
        if(!context.JK.guardAgainstBrowser(app)) {
          return false;
        }

        if(createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_QUICK_START %>' || createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_QUICK_PUBLIC %>') {
          // short-cut added for private sessions; just get it going
          beforeMoveStep1(); // this will populate the createSessionSettings structure
          startSessionClicked(); // and this will create the session
          return false;
        }
      }

      if(optionRequiresMultiplayerProfile()) {
       // if(context.JK.guardAgainstSinglePlayerProfile(app).canPlay == false) {
        //  return false;
        //}
      }

      var valid = beforeMoveStep();
      if (!valid) {
        console.log("beforeMoveStep check invalid")
        return false;
      }

      if (event) {
        event.preventDefault();
      }
      if ($(this).is('.disabled')) return false;

      if ($.inArray(createSessionSettings.createType, ['<%= MusicSession::CREATE_TYPE_START_SCHEDULED%>', '<%= MusicSession::CREATE_TYPE_QUICK_START %>', '<%= MusicSession::CREATE_TYPE_QUICK_PUBLIC %>']) > -1)
        step = STEP_SELECT_CONFIRM;
      else
        step++;

      moveToStep();
      return false;
    }

    function beforeShowStep() {
      var stepInfo = STEPS[step];

      if (!stepInfo) {
        throw "unknown step: " + step;
      }

      toggleStepStatus();

      stepInfo.beforeShow.call(self);
    }

    function beforeMoveStep() {
      var stepInfo = STEPS[step];

      if (!stepInfo) {
        throw "unknown step: " + step;
      }

      return stepInfo.beforeMove.call(self);
    }

    function reset() {
      $selectedFilenames.empty(); // we need to be sure and clear out old uploaded notations on every start of create session flow
    }

    function beforeShow(args) {

      reset();
      step = args.d1;
      if (!step) step = 0;
      step = parseInt(step);
      firstTimeShown = true;
      moveToStep();
    }

    function afterShow() {
      context.JK.HelpBubbleHelper.jamtrackGuidePrivate($screen.find('li[create-type="quick-start"] label'), $screen.find('.content-body-scroller'))
    }

    function beforeHide() {
      context.JK.HelpBubbleHelper.clearJamTrackGuide();
    }

    function toggleDate(dontRebuildDropdowns) {
      var selectedDate = new Date($screen.find('#session-start-date').val());
      var currentDate = new Date();
      var startIndex = 0;

      if (currentDate.getYear() == selectedDate.getYear() &&
        currentDate.getMonth() == selectedDate.getMonth() &&
        currentDate.getDate() == selectedDate.getDate()) {

        var timeString = context.JK.formatUtcTime(currentDate, true);
        startIndex = defaultTimeArray.indexOf(timeString);
      }
      $startTimeList.empty();
      for (var i = startIndex; i < defaultTimeArray.length; i++) {
        var strTime = defaultTimeArray[i];
        $startTimeList.append($('<option value="' + strTime + '" class="label">' + strTime +'</option>'));
      }

      if (createSessionSettings.startTime != selectedDate)
        createSessionSettings.startTime = defaultTimeArray[startIndex];
      $startTimeList.val(createSessionSettings.startTime);

      toggleStartTime(dontRebuildDropdowns);
    }

    function toggleStartTime(dontRebuildDropdowns) {
      var valueSelected = $startTimeList.find('option:selected').val();
      var startIndex = defaultTimeArray.indexOf(valueSelected) + 1;

      var $endTimeList = $('#end-time-list');
      $endTimeList.empty();
//      if (startIndex == defaultTimeArray.length ) {
//        var strTime = defaultTimeArray[0];
//        $endTimeList.append($('<option value="' + strTime + '" class="label">' + strTime +'</option>'));
//      }

      var endIndex = startIndex + 6;
      var endTimeIndices = [];
      for (var i = startIndex; i < endIndex; i++) {
        if (i <= defaultTimeArray.length - 1) {
          endTimeIndices.push(i);
        }
        else {
          endTimeIndices.push(i - defaultTimeArray.length);
        }
      }

      $.each(endTimeIndices, function(index, value) {
        var strTime = defaultTimeArray[value];
        $endTimeList.append($('<option value="' + strTime + '" class="label">' + strTime +'</option>'));
      });

      if (createSessionSettings.endTime != defaultTimeArray[startIndex + 1]) {
        createSessionSettings.endTime = defaultTimeArray[(startIndex + 1) % defaultTimeArray.length];
      }

      $endTimeList.val(createSessionSettings.endTime);

      if(!dontRebuildDropdowns) {
        logger.debug("rebuilding start/end time dropdowns")
        context.JK.dropdown($startTimeList);
        context.JK.dropdown($endTimeList);
      }

    }

    function initializeControls() {
      $("#create-session-form").iCheck({
        checkboxClass: 'icheckbox_minimal',
        radioClass: 'iradio_minimal',
        inheritClass: true
      });
      $screen.find("#session-start-date").datepicker({
          dateFormat: "D d MM yy",
          onSelect: function() { toggleDate(); }
        }
      );

      context.JK.GenreSelectorHelper.render('#create-session-genre');

      if(context.JK.currentUserId) {
        inviteMusiciansUtil.loadFriends();
      }

      context.JK.dropdown($screen.find('#session-musician-access'));
      context.JK.dropdown($screen.find('#session-fans-access'));
      context.JK.dropdown($screen.find('#session-friends-can-join'));
      context.JK.dropdown($timezoneList);
      context.JK.dropdown($recurringModeList);
      context.JK.dropdown($languageList);
      context.JK.dropdown($bandList);

      context.JK.helpBubble($sessionPlusMusiciansLabel, 'session-plus-musicians', {}, {offsetParent: $sessionPlusMusiciansLabel.closest('.content-wrapper')});

      $editScheduledSessions.on('click', onEditSessions);

      context.JK.popExternalLinks($screen)
    }

    function changeSelectedFiles() {
      var fileNames = [];
      var files = $inputFiles.get(0).files;
      var error = false;
      for (var i = 0; i < files.length; ++i) {
        var name = files.item(i).name;
        var ext = name.split('.').pop().toLowerCase();
        if ($.inArray(ext, ["pdf", "png", "jpg", "jpeg", "gif", "xml", "mxl", "txt"]) == -1) {
          error = true;
          break;
        }
        fileNames.push(name);
      }

      if (error) {
        app.notifyAlert("Error", "We're sorry, but you can only upload images (.png .jpg .jpeg .gif), text (.txt), PDFs (.pdf), and XML files (.xml .mxl).");
        $inputFiles.replaceWith($inputFiles.clone(true));
      }
      else {
      // upload as soon as user picks their files.
        uploadNotations($inputFiles.get(0).files)
          .done(function() {
            context._.each(fileNames, function(fileName) {
              var $text = $('<span>').text(fileName);
              var $file = $('<li>').append($text);
              $selectedFilenames.append($file);
            })
          })
      }
    }

    function toggleSelectFiles(event) {
      if($btnSelectFiles.data('uploading')) {
        logger.debug("ignoring click of SELECT FILES... while uploading")
        return false;
      }

      event.preventDefault();
      $inputFiles.trigger('click');
      return false;
    }

    function toggleStepStatus() {
      $screen.find('#create-session-steps .session-stepnumber').off('click');
      $screen.find('#create-session-steps .session-stepnumber').removeClass('session-stephover');

      if ($.inArray(createSessionSettings.createType, ['<%= MusicSession::CREATE_TYPE_START_SCHEDULED%>', '<%= MusicSession::CREATE_TYPE_QUICK_START %>']) > -1) {
        if (step == STEP_SELECT_CONFIRM) {
          for (var i = 2; i < 5; i++) {
            $screen.find('#create-session-steps .session-stepnumber[data-step-number="' + i + '"]').hide();
          }
          $screen.find('#create-session-steps .session-stepnumber[data-step-number="5"]').html("2");
          $screen.find('#create-session-steps .session-stepnumber[data-step-number="1"]').on('click', back);
          $screen.find('#create-session-steps .session-stepnumber[data-step-number="1"]').addClass('session-stephover');
        }
        else if (step == STEP_SELECT_TYPE) {
          for (var i = 3; i < 6; i++) {
            $screen.find('#create-session-steps .session-stepnumber[data-step-number="' + i + '"]').hide();
          }
          $screen.find('#create-session-steps .session-stepnumber[data-step-number="5"]').html("5");
          var $nextStep = $screen.find('#create-session-steps .session-stepnumber[data-step-number="2"]');
          if (createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_QUICK_START %>') {
            $nextStep.on('click', next);
            $nextStep.addClass('session-stephover')
          }
          else if (createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_START_SCHEDULED%>' && createSessionSettings.session_count > 0) {
            $nextStep.on('click', next);
            $nextStep.addClass('session-stephover')
          }
        }
      }
      else {
        $screen.find('#create-session-steps').find('.session-stepnumber').show();
        $screen.find('#create-session-steps .session-stepnumber[data-step-number="' + (step + 1) + '"]').on('click', next);
        $screen.find('#create-session-steps .session-stepnumber[data-step-number="' + (step + 1) + '"]').addClass('session-stephover');
        $screen.find('#create-session-steps .session-stepnumber[data-step-number="' + (step - 1) + '"]').on('click', back);
        $screen.find('#create-session-steps .session-stepnumber[data-step-number="' + (step - 1) + '"]').addClass('session-stephover');
      }
    }

    function toggleCreateType(event, checkedType) {

      if(!checkedType) {
        var $checkedType = $(event.target);
        var checkedType = $checkedType.attr('info-value');
      }

      if (checkedType == createSessionSettings.createType) return;

      $createTypeHelpers.addClass('hidden');
      var $checkedInfo = $screen.find('.session-when-info div[info-id=' + '"' + checkedType + '"]');
      $checkedInfo.removeClass('hidden');

      createSessionSettings.createType = checkedType;

      if (createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_START_SCHEDULED%>') {
        $('#start-scheduled-wrapper').show();
        $('#schedule-future-wrapper').hide();
        createSessionSettings.timezone = {};
        createSessionSettings.recurring_mode = {};
        createSessionSettings.timezone = {};
        createSessionSettings.language = {};
        createSessionSettings.band = {};
        createSessionSettings.musician_access = {};
        createSessionSettings.fans_access = {};
      }
      else if (createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_SCHEDULE_FUTURE %>') {
        $('#start-scheduled-wrapper').hide();
        $('#schedule-future-wrapper').show();
      }
      else
      {
        $('#start-scheduled-wrapper').hide();
        $('#schedule-future-wrapper').hide();
      }

      var $btnNext = $('#create-session-buttons .btn-next');
      if (step == STEP_SELECT_TYPE && createSessionSettings.createType == '<%= MusicSession::CREATE_TYPE_START_SCHEDULED%>' && createSessionSettings.selectedSessionId == null) {
        $btnNext.addClass('disabled')
      }
      else {
        $btnNext.removeClass('disabled');
      }

      toggleStepStatus();
    }

    function togglePolicyTypeChanged(event) {
      $('#session-policy-info .info-box').addClass('hidden');
      $('#session-policy-info .info-box[policy-type="' + $(event.target).attr('policy-id') + '"]').removeClass('hidden');
    }

    function toggleMusicianAccessTypes(event) {
      $('#session-musician-access-info .info-box').addClass('hidden');
      $('#session-musician-access-info .info-box[musician-access-type="' + $(event.target).val() + '"]').removeClass('hidden');
    }

    function toggleFanAccessTypes(event) {
      $('#session-fans-access-info .info-box').addClass('hidden');
      $('#session-fans-access-info .info-box[fans-access-type="' + $(event.target).val() + '"]').removeClass('hidden');
    }

    function toggleFriendsCanJoinTypes(event) {
      $('#session-friends-can-join-info .info-box').addClass('hidden');
      $('#session-friends-can-join-info .info-box[friends-can-join-type="' + $(event.target).val() + '"]').removeClass('hidden');
    }

    function selectBand() {
      var bandId = $bandList.get(0).options[$bandList.get(0).selectedIndex].value;
      if (bandId != '') {
        var url = "/api/bands/" + bandId + "/musicians";
        return $.ajax({
           type: "GET",
           dataType: "json",
           url: url,
           processData:false,
           error: app.ajaxError
        })
        .done(function(response) {
           $.each(response, function(index, val) {
             if (val.id !== context.JK.currentUserId) {
               inviteMusiciansUtil.addInvitationIfAbsent(val.name, val.id);
             }
           });
         })
      }
    }

    // asks the instrument selector for the creator's specified instruments, and defaults to Other/Beginner if none were selected
    function getCreatorInstruments() {
      var instruments = instrumentSelector.getSelectedInstruments();
      if(instruments.length == 0) {
        var otherId = context.JK.server_to_client_instrument_map.Other.server_id; // get server ID
        var otherInstrumentInfo = context.JK.instrument_id_to_instrument[otherId]; // get display name
        var beginnerLevel  = 1; // default to beginner
        instruments = [ {id: otherId, name: otherInstrumentInfo.display, level: beginnerLevel} ];
      }
      return instruments;
    }

    function events() {
      $createTypes.on("ifChanged", toggleCreateType);
      $startTimeList.on('change', function() { toggleStartTime(); });
      $policyTypes.on("ifChanged", togglePolicyTypeChanged);
      $('#session-step-5 #session-musician-access').on('change', toggleMusicianAccessTypes);
      $('#session-step-5 #session-fans-access').on('change', toggleFanAccessTypes);
      $('#session-step-5 #session-friends-can-join').on('change', toggleFriendsCanJoinTypes);


      $('div[layout-id="createSession"] .btn-email-invitation').click(function() {
        invitationDialog.showEmailDialog();
      });

      $('div[layout-id="createSession"] .btn-gmail-invitation').click(function() {
        invitationDialog.showGoogleDialog();
      });

      $('div[layout-id="createSession"] .btn-facebook-invitation').click(function(e) {
        invitationDialog.showFacebookDialog(e);
      });

      $(friendInput).focus(function() { $(this).val(''); });
      $bandList.on('change', function() { selectBand() } );

      $inputFiles.on('change', changeSelectedFiles);
      $btnSelectFiles.on('click', toggleSelectFiles);

      $quickStartSoloBtn.on('click', clickQuickStartSolo)
      $quickStartFriendsBtn.on('click', clickQuickStartFriends)
      $quickStartOpenBtn.on('click', clickQuickStartPublic)
      $startOrScheduledBtn.on('click', clickStartOrSchedule)
    }

    function initialize(invitationDialogInstance, friendSelectorDialog, instrumentSelectorInstance, instrumentRSVPSelectorInstance) {

      inviteMusiciansUtil = new JK.InviteMusiciansUtil(app);
      inviteMusiciansUtil.initialize(friendSelectorDialog);

      invitationDialog = invitationDialogInstance;
      friendInput = inviteMusiciansUtil.inviteSessionCreate('#create-session-invite-musicians', "<h3>Who do you want to invite?</h3>");  //'

      instrumentSelector = instrumentSelectorInstance;
      instrumentRSVP = instrumentRSVPSelectorInstance;

      var screenBindings = {'beforeShow': beforeShow, 'afterShow': afterShow, 'beforeHide' : beforeHide};
      app.bindScreen('createSession', screenBindings);

      $wizardSteps = $screen.find('.create-session-wizard');
      $templateSteps = $('#template-session-steps');
      $templateButtons = $('#template-session-buttons');
      $sessionButtons = $('#create-session-buttons');
      $startTimeList = $screen.find('#start-time-list');
      $endTimeList = $screen.find('#end-time-list');
      $timezoneList = $screen.find('#timezone-list');
      $recurringModeList = $screen.find('#recurring-mode-list');
      $screenStep1 = $screen.find('#session-step-1');
      $createTypes = $screen.find('input[name="session-when"]');
      $createTypeHelpers = $screen.find('.session-when-info div');
      $scheduledSessions = $screenStep1.find("#scheduled-session-list");
      $languageList = $screen.find('#session-language-list');
      $bandList = $screen.find('#session-band-list');
      $sessionPlusMusiciansLabel = $screen.find('label[for="session-plus-musicians"]');
      $editScheduledSessions = $screen.find('#edit_scheduled_sessions');
      $btnSelectFiles = $screen.find('#session-notation-file-selection');
      $selectedFilenames = $screen.find('#selected-filenames');
      $uploadSpinner = $screen.find('#file-upload-spinner');
      $policyTypes = $screen.find('input[name="session-policy-type"]');
      $fetchingSpinner = $screen.find('#fetching-spinner');
      $fetchingSpinnerLabel = $screen.find('#fetching-spinner-label');
      $noSessionFound = $screen.find("#scheduled-session-not-found");
      $sessionHeader = $screen.find('.session-header')
      $quickStartSoloBtn = $screen.find('.quick-start-solo')
      $quickStartFriendsBtn = $screen.find('.quick-start-friends')
      $quickStartOpenBtn = $screen.find('.quick-start-open')
      $startOrScheduledBtn = $screen.find('.start-or-schedule')
      $featureSessions = $screen.find('.featured-sessions tbody')

      initializeControls();
      events();
    }

    this.initialize = initialize;

    return this;
  }

})(window, jQuery);