(function (context, $) {

    "use strict";

    context.JK = context.JK || {};
    context.JK.ProfileScreen = function (app) {
      var logger = context.JK.logger;
      var userId;
      var user = null;
      var userDefer = null;
      var rest = context.JK.Rest();
      var decrementedFriendCountOnce = false;
      var sentFriendRequest = false;
      var textMessageDialog = null;
      var feed = null;
      var player = null;
      var profileUtils = context.JK.ProfileUtils;
      var EVENTS = context.JK.EVENTS;

      var NOT_SPECIFIED_TEXT = 'Not specified';

      var $screen = $('#user-profile');

      var $biography = $screen.find('#biography');

      // musical experience
      var $instruments = $screen.find('.instruments-holder');
      var $musicianStatus = $screen.find('#musician-status');
      var $genres = $screen.find('#genres');
      var $concertCount = $screen.find('#concert-count');
      var $studioCount = $screen.find('#studio-count');

      // performance samples
      var $noSamples = $screen.find('.no-samples');
      var $jamkazamSamples = $screen.find('.jamkazam-samples');
      var $soundCloudSamples = $screen.find('.soundcloud-samples');
      var $youTubeSamples = $screen.find('.youtube-samples');

      // online presence

      var $userWebsite = $screen.find('.user-website');
      var $soundCloudPresence = $screen.find('.soundcloud-presence');
      var $reverbNationPresence = $screen.find('.reverbnation-presence');
      var $bandCampPresence = $screen.find('.bandcamp-presence');
      var $fandalismPresence = $screen.find('.fandalism-presence');
      var $youTubePresence = $screen.find('.youtube-presence');
      var $facebookPresence = $screen.find('.facebook-presence');
      var $twitterPresence = $screen.find('.twitter-presence');

      // current interests
      var $noInterests = $screen.find('#no-interests');
      var $paidGigSection = $screen.find('#paid-gigs');
      var $paidGigDetails = $screen.find('#paid-gig-details');

      var $freeGigSection = $screen.find('#free-gigs');
      var $freeGigDetails = $screen.find('#free-gig-details');

      var $cowritingSection = $screen.find('#cowriting');
      var $cowritingDetails = $screen.find('#cowriting-details');

      var $traditionalBandSection = $screen.find('#traditional-band');
      var $traditionalBandDetails = $screen.find('#traditional-band-details');

      var $virtualBandSection = $screen.find('#virtual-band');
      var $virtualBandDetails = $screen.find('#virtual-band-details');

      // tabs
      var $aboutLink = $screen.find('#about-link');
      var $aboutContent = $screen.find('#about-content');

      var $historyLink = $screen.find('#history-link');
      var $historyContent = $screen.find('#history-content');

      var $bandsLink = $screen.find('#bands-link');
      var $bandsContent = $screen.find('#bands-content');

      var $socialLink = $screen.find('#social-link');
      var $socialContent = $screen.find('#social-content');

      var $favoritesLink = $screen.find('#favorites-link');
      var $favoritesContent = $screen.find('#favorites-content');

      // stats
      var $friendStats = $screen.find('#friend-stats');
      var $followerStats = $screen.find('#follower-stats');
      var $sessionStats = $screen.find('#session-stats');
      var $recordingStats = $screen.find('#recording-stats');
      var $followingStats = $screen.find('#following-stats');
      var $favoriteStats = $screen.find('#favorite-stats');

      // miscellaneous
      var $userName = $screen.find('#username');
      var $avatar = $screen.find('#avatar');
      var $typeLabel = $screen.find('#type-label');
      var $location = $screen.find('#location');
      var $age = $screen.find('#age');

      // buttons
      var $profileActions = $screen.find('.profile-actions')
      var $btnEdit = $screen.find('.edit-profile-btn');
      var $btnTeacherProfileEdit = $screen.find('.edit-teacher-profile-btn');
      var $btnTeacherProfileView = $screen.find('.view-teacher-profile-btn');
      var $toggleTeacherSearchEnabled = $screen.find('.teacher-search-enabled')
      var $btnAddFriend = $screen.find('#btn-add-friend');
      var $btnFollowUser = $screen.find('#btn-follow-user');
      var $btnMessageUser = $screen.find('#btn-message-user');
      var $btnEditBio = $screen.find(".add-bio");
      var $btnAddRecordings = $screen.find('.add-recordings');
      var $btnAddSites = $screen.find('.add-sites');
      var $btnAddInterests = $screen.find('.add-interests');
      var $btnAddExperiences = $screen.find('.add-experiences')

      // social
      var $socialLeft = $screen.find('.profile-social-left');
      var $socialFriends = $screen.find('#social-friends');
      var $socialFollowings = $screen.find('#social-followings');
      var $socialFollowers = $screen.find('#social-followers');

      var instrument_logo_map = context.JK.getInstrumentIconMap24();

      function beforeShow(data) {
        userId = data.id;
        feed.setUser(userId);
      }

      function afterShow(data) {
        initUser();
        resetForm();
        renderAllStats();

        autoShowRatingDialogIfNeeded();
      }

      function autoShowRatingDialogIfNeeded() {

        if ($.QueryString['selected']) {
          var rewrite = true
          app.layout.showDialog('rate-user-dialog', {d1: "student_" + userId}).one(EVENTS.DIALOG_CLOSED, function (e, data) {
            if (!data.canceled) {

            }
          })
        }

        if (rewrite) {
          if (window.history.replaceState) {//ie9 proofing
            window.history.replaceState({}, "", "/client#/profile/" + userId)
          }
        }
      }

      function beforeHide(data) {
        feed.setUser(null);
      }

      function resetForm() {
        //$instruments.empty();

        $aboutContent.show();
        $historyContent.hide();
        $bandsContent.hide();
        $socialContent.hide();
        $favoritesContent.hide();

        $('.profile-nav a.active').removeClass('active');
        $aboutLink.addClass('active');
      }

      function initUser() {
        user = null;
        decrementedFriendCountOnce = false;
        sentFriendRequest = false;
        userDefer = rest.getUserProfile({id: userId, show_teacher: true})
          .done(function (response) {
            user = response;
            configureUserType();
            renderActive();
            renderAllStats();
          })
          .fail(function (jqXHR) {
            if (jqXHR.status >= 500) {
              context.JK.fetchUserNetworkOrServerFailure();
            }
            else if (jqXHR.status == 404) {
              context.JK.entityNotFound("User");
            }
            else {
              app.ajaxError(arguments);
            }
          });
      }

      function isMusician() {
        return user.musician;
      }

      function isTeacher() {
        return user.teacher;
      }

      function isCurrentUser() {
        return userId === context.JK.currentUserId;
      }

      function configureUserType() {
        if (isMusician()) {
          $historyLink.show();
          $bandsLink.show();
          $instruments.show();
          $sessionStats.show();
          $recordingStats.show();
          // $followingStats.hide();
          // $favoriteStats.hide();
          $socialLeft.show();
          $typeLabel.text('musician');
          $location.text('Location');
        } else {
          $historyLink.hide();
          $bandsLink.hide();
          $instruments.hide();
          $sessionStats.hide();
          $recordingStats.hide();
          // $followingStats.show();
          // $favoriteStats.show();
          $socialLeft.hide();
          $typeLabel.text('fan');
          $location.text('Presence');
        }

        if (isCurrentUser()) {
          $profileActions.show()
          $btnEdit.show();
          $btnTeacherProfileEdit.show();
          if (isTeacher()) {
            $btnTeacherProfileView.show();
            $toggleTeacherSearchEnabled.show()
          }
          else {
            $btnTeacherProfileView.hide();
            $toggleTeacherSearchEnabled.hide()
          }
          $btnAddFriend.hide();
          $btnFollowUser.hide();
          $btnMessageUser.hide();
        } else {
          configureFriendFollowersControls();

          $profileActions.hide();
          $btnEdit.hide();
          $btnTeacherProfileEdit.hide();
          $btnTeacherProfileView.show();
          $btnAddFriend.show();
          $btnFollowUser.show();
          $btnMessageUser.show();
        }
      }

      function configureFriendFollowersControls() {
        // wire up Add Friend click
        configureFriendButton();

        // wire up Follow click
        configureFollowingButton();
      }

      /****************** MAIN PORTION OF SCREEN *****************/
      // events for main screen
      function events() {
        // wire up panel clicks -- these need to check deferred because they can't be hidden when in an invalid state
        $aboutLink.click(function () {
          renderTabDeferred(renderAbout)
        });

        $historyLink.click(function () {
          renderTabDeferred(renderHistory)
        });

        $bandsLink.click(function () {
          renderTabDeferred(renderBands)
        });

        $socialLink.click(function () {
          renderTabDeferred(renderSocial)
        });

        $favoritesLink.click(function () {
          renderTabDeferred(renderFavorites)
        });

        // this doesn't need deferred because it's only shown when valid
        $btnAddFriend.click(handleFriendChange);
        $btnFollowUser.click(handleFollowingChange);
        $btnMessageUser.click(handleMessageMusician);

        // Hook up soundcloud player:
        $soundCloudSamples.off("click", "a.sound-cloud-playable").on("click", "a.sound-cloud-playable", playSoundCloudFile)

        $btnEdit.click(function (e) {
          e.preventDefault()
          window.ProfileActions.startProfileEdit(null, false)
          return false;
        })
        $btnTeacherProfileEdit.click(function (e) {
          e.preventDefault()
          window.ProfileActions.startTeacherEdit(null, false)
          return false;
        })
        $btnTeacherProfileView.click(function (e) {
          e.preventDefault()
          context.location = '/client#/profile/teacher/' + context.JK.currentUserId;
          return false;
        })
        $btnEditBio.click(function (e) {
          e.preventDefault()
          window.ProfileActions.startProfileEdit(null, true)
          return false;
        })
        $btnAddRecordings.click(function (e) {
          e.preventDefault()
          window.ProfileActions.startProfileEdit('samples', true)
          return false;
        })
        $btnAddSites.click(function (e) {
          e.preventDefault()
          window.ProfileActions.startProfileEdit('samples', true)
          return false;
        })
        $btnAddInterests.click(function (e) {
          e.preventDefault()
          window.ProfileActions.startProfileEdit('interests', true)
          return false;
        });
        $btnAddExperiences.click(function (e) {
          e.preventDefault()
          window.ProfileActions.startProfileEdit('experience', true)
          return false;
        })
        $toggleTeacherSearchEnabled.find('input').change(function(e) {
          var $check = $(this)
          rest.updateTeacher({id: user.teacher.id, is_searchable: $check.is(':checked')})
              .fail(app.ajaxError);
        })
      }

      function playSoundCloudFile(e) {
        e.preventDefault();
        var url = $(this).attr("soundcloud_url")
        var cap = $(this).text()
        player.initialize(url, cap);
        app.layout.showDialog('sound-cloud-player-dialog');
        return false;
      }

      function handleFriendChange(evt) {
        if (isFriend()) {
          removeFriend(evt);
        } else {
          sendFriendRequest(evt);
        }
        return false;
      }

      function handleFollowingChange(evt) {
        if (isFollowing()) {
          removeFollowing(false, userId);
        } else {
          addFollowing();
        }
        return false;
      }

      function handleMessageMusician(evt) {
        app.layout.showDialog('text-message', {d1: userId});
        return false;
      }

      function sendFriendRequest(evt) {
        evt.stopPropagation();
        setFriend(true); // TODO: you aren't a friend yet. just a request to be one really there are 3 states here.
        sentFriendRequest = true;
        rest.sendFriendRequest(app, userId, friendRequestCallback);
      }

      function removeFriend(evt) {
        evt.stopPropagation();

        rest.removeFriend({friend_id: userId})
          .done(function () {
            updateFriendCount(-1);
            setFriend(false);
            configureFriendButton();
          })
          .fail(app.ajaxError);
      }

      function isFriend() {
        return user.is_friend;
      }

      function setFriend(isFriend) {
        user.is_friend = isFriend;
      }

      function friendRequestCallback() {
        configureFriendButton();
      }

      function configureFriendButton() {
        if (isFriend()) {
          $btnAddFriend.text('DISCONNECT');
        } else {
          $btnAddFriend.text('CONNECT');
        }
      }

      function addFollowing() {

        rest.addFollowing({user_id: userId})
          .done(function () {
            updateFollowingCount(1);
            setFollowing(true);
            configureFollowingButton();
            context.JK.GA.trackJKSocial(context.JK.GA.Categories.jkFollow, isMusician() ? context.JK.GA.JKSocialTargets.musician : context.JK.GA.JKSocialTargets.fan);
          })
          .fail(app.ajaxError);
      }

      function removeFollowing(isBand, id) {
        rest.removeFollowing(id)
          .done(function () {
            if (!isBand) {
              updateFollowingCount(-1);
              setFollowing(false);
              configureFollowingButton();
            }
            else {
              updateBandFollowingCount(id, -1);  // refresh stats
              configureBandFollowingButton(false, id);
            }
          })
          .fail(app.ajaxError);
      }

      function isFollowing() {
        return user.is_following;
      }

      function setFollowing(isFollowing) {
        user.is_following = isFollowing;
      }

      function configureFollowingButton() {

        if (isFollowing()) {
          $btnFollowUser.text('UNFOLLOW');
        } else {
          $btnFollowUser.text('FOLLOW');
        }
      }

      function configureEditProfileButton() {
        $btnFollowUser.click(addFollowing);
      }

      // refreshes the currently active tab
      function renderActive() {
        if ($aboutLink.hasClass('active')) {
          renderAbout();
        }
        else if ($historyLink.hasClass('active')) {
          renderHistory();
        }
        else if ($bandsLink.hasClass('active')) {
          renderBands();
        }
        else if ($socialLink.hasClass('active')) {
          renderSocial();
        }
        else if ($favoritesLink.hasClass('active')) {
          renderFavorites();
        }
      }

      function renderTabDeferred(tabRenderer) {
        userDefer
          .done(function () {
            tabRenderer();
          })
          .fail(function () {
            // try again
            initUser();
          })
      }

      function hideElements(elements) {
        $.each(elements, function (index, val) {
          val.hide();
        });
      }

      /****************** ABOUT TAB *****************/
      function renderAbout() {
        //$instruments.empty();

        $aboutContent.show();
        $historyContent.hide();
        $bandsContent.hide();
        $socialContent.hide();
        $favoritesContent.hide();

        $('.profile-nav a.active').removeClass('active');
        $aboutLink.addClass('active');
      }

      function renderAllStats() {

        if (!isCurrentUser()) {
          $btnEditBio.hide();
          $btnAddRecordings.hide();
          $btnAddSites.hide();
          $btnAddInterests.hide();
        }

        if (user && $userName) {
          renderNameLocationStats();
          renderBio();
          renderMusicalExperience();
          renderPerformanceSamples();
          renderOnlinePresence();
          renderInterests();
          renderTeacherSearch();
        }
      }

      function renderNameLocationStats() {
        // name
        $userName.html(user.name);

        // avatar
        $avatar.attr('src', context.JK.resolveAvatarUrl(user.photo_url));

        // location
        $location.html(user.location);

        //$age.html(user.age ? user.age + " years old" : "");

        // stats
        var text = user.friend_count > 1 || user.friend_count === 0 ? " Friends" : " Friend";
        $friendStats.html('<span class="friend-count">' + user.friend_count + '</span>' + text);

        text = user.follower_count > 1 || user.follower_count === 0 ? " Followers" : " Follower";
        $followerStats.html('<span class="follower-count">' + user.follower_count + '</span>' + text);

        if (isMusician()) {
          text = user.session_count > 1 || user.session_count === 0 ? " Sessions" : " Session";
          $sessionStats.html(user.session_count + text);

          text = user.recording_count > 1 || user.recording_count === 0 ? " Recordings" : " Recording";
          $recordingStats.html(user.recording_count + text);
        } else {
          text = " Following";
          $followingStats.html(user.following_count + text);
          text = user.favorite_count > 1 || user.favorite_count === 0 ? " Favorites" : " Favorite";
          $favoriteStats.html(user.favorite_count + text);
        }
      }

      function renderBio() {
        $biography.html(user.biography ? user.biography : NOT_SPECIFIED_TEXT);
        if (isCurrentUser()) {
          $btnEditBio.show();
        } else {
          $btnEditBio.hide();
        }
      }

      function renderTeacherSearch()
      {
        if(isTeacher())
        {
          if(user.teacher.is_searchable )
          {
            $toggleTeacherSearchEnabled.find('input').attr('checked', 'checked')
          }
          else
          {
            $toggleTeacherSearchEnabled.find('input').removeAttr('checked')
          }


        }

      }
      function renderMusicalExperience() {
        profileUtils.renderMusicalExperience(user, $screen, isCurrentUser())
      }

      function renderPerformanceSamples() {
        profileUtils.renderPerformanceSamples(user, $screen, isCurrentUser())
      }

      function renderOnlinePresence() {
        profileUtils.renderOnlinePresence(user, $screen, isCurrentUser())
      }

      function renderInterests() {
        // current interests
        if (isCurrentUser()) {
          $btnAddInterests.show();
        }
        else {
          $btnAddInterests.hide();
        }

        var noInterests = !user.paid_sessions && !user.free_sessions && !user.cowriting && !user.virtual_band && !user.traditional_band;
        if (noInterests) {
          $noInterests.show();
          $paidGigSection.hide();
          $freeGigSection.hide();
          $cowritingSection.hide();
          $traditionalBandSection.hide();
          $virtualBandSection.hide();
        } else {
          $noInterests.hide();

          // paid sessions
          if (user.paid_sessions) {
            $paidGigSection.show();

            var genreList = profileUtils.paidSessionGenreList(user.genres);
            $paidGigDetails.find("ul").html("");
            $paidGigDetails.find("ul").append('<li>Genre(s): ' + (genreList.length > 0 ? genreList : NOT_SPECIFIED_TEXT) + '</li>');

            var hourlyRate = user.paid_sessions_hourly_rate;
            $paidGigDetails.find("ul").append('<li>Hourly rate = ' + (hourlyRate ? hourlyRate : NOT_SPECIFIED_TEXT) + '</li>');

            var dailyRate = user.paid_sessions_daily_rate;
            $paidGigDetails.find("ul").append('<li>Day rate = ' + (dailyRate ? dailyRate : NOT_SPECIFIED_TEXT) + '</li>');
          } else {
            $paidGigSection.hide();
          }

          // free sessions
          if (user.free_sessions) {
            $freeGigSection.show();
            $freeGigDetails.find("ul").html("");
            var genreList = profileUtils.freeSessionGenreList(user.genres);
            $freeGigDetails.find("ul").append('<li>Genre(s): ' + (genreList.length > 0 ? genreList : NOT_SPECIFIED_TEXT) + '</li>');
          } else {
            $freeGigSection.hide();
          }

          // cowriting
          if (user.cowriting) {
            $cowritingSection.show();
            $cowritingDetails.find("ul").html("");
            var genreList = profileUtils.cowritingGenreList(user.genres);
            $cowritingDetails.find("ul").append('<li>Genre(s): ' + (genreList.length > 0 ? genreList : NOT_SPECIFIED_TEXT) + '</li>');

            var purpose = user.cowriting_purpose;
            $cowritingDetails.find("ul").append('<li>Purpose: ' + (purpose ? profileUtils.cowritingPurposeMap[purpose] : NOT_SPECIFIED_TEXT) + '</li>');
          } else {
            $cowritingSection.hide();
          }

          // traditional bands
          if (user.traditional_band) {
            $traditionalBandSection.show();
            $traditionalBandDetails.find("ul").html("");
            var genreList = profileUtils.traditionalBandGenreList(user.genres);
            $traditionalBandDetails.find("ul").append('<li>Genre(s): ' + (genreList.length > 0 ? genreList : NOT_SPECIFIED_TEXT) + '</li>');

            var commitment = user.traditional_band_commitment;
            $traditionalBandDetails.find("ul").append('<li>Commitment: ' + (commitment ? profileUtils.bandCommitmentMap[commitment] : NOT_SPECIFIED_TEXT) + '</li>');

            var canTour = user.traditional_band_touring;
            var canTourResponse = canTour ? "Yes" : (canTour === false ? "No" : NOT_SPECIFIED_TEXT);
            $traditionalBandDetails.find("ul").append('<li>Touring: ' + canTourResponse + '</li>');
          } else {
            $traditionalBandSection.hide();
          }

          // virtual band
          if (user.virtual_band) {
            $virtualBandSection.show();
            $virtualBandDetails.find("ul").html("");
            var genreList = profileUtils.virtualBandGenreList(user.genres);
            $virtualBandDetails.find("ul").append('<li>Genre(s): ' + (genreList.length > 0 ? genreList : NOT_SPECIFIED_TEXT) + '</li>');

            var commitment = user.virtual_band_commitment;
            $virtualBandDetails.find("ul").append('<li>Commitment: ' + (commitment ? profileUtils.bandCommitmentMap[commitment] : NOT_SPECIFIED_TEXT) + '</li>');
          } else {
            $virtualBandSection.hide();
          }
        }
      }

      /****************** SOCIAL TAB *****************/
      function renderSocial() {
        $socialFriends.empty();
        $socialFollowings.empty();
        $socialFollowers.empty();

        $aboutContent.hide();
        $historyContent.hide();
        $bandsContent.hide();
        $socialContent.show();
        $favoritesContent.hide();

        $('.profile-nav a.active').removeClass('active');
        $socialLink.addClass('active');

        bindSocial();
      }

      function bindSocial() {
        if (isMusician()) {
          // FRIENDS
          rest.getFriends({id: userId})
            .done(function (response) {
              if (response && response.length > 0) {
                $.each(response, function (index, val) {
                  var template = $('#template-profile-social').html();
                  var friendHtml = context.JK.fillTemplate(template, {
                    userId: val.id,
                    hoverAttributeId: "user-id",
                    hoverAction: val.musician ? "musician" : "fan",
                    avatar_url: context.JK.resolveAvatarUrl(val.photo_url),
                    userName: val.name,
                    location: val.location,
                    type: "Friends"
                  });

                  $socialFriends.append(friendHtml);
                });
              }
              else {
                $socialFriends.html('&nbsp;');
              }
              context.JK.bindHoverEvents();
            })
            .fail(app.ajaxError)
        }

        rest.getFollowings({id: userId})
          .done(function (response) {
            if (response && response.length > 0) {
              $.each(response, function (index, val) {
                var template = $('#template-profile-social').html();
                var followingHtml = context.JK.fillTemplate(template, {
                  userId: val.id,
                  hoverAttributeId: val.type === "user" ? "user-id" : "band-id",
                  hoverAction: val.type === "user" ? (val.musician ? "musician" : "fan") : "band",
                  avatar_url: context.JK.resolveAvatarUrl(val.photo_url),
                  userName: val.name,
                  location: val.location
                });

                $socialFollowings.append(followingHtml);
              });
            }
            else {
              $socialFollowings.html('&nbsp;');
            }
            context.JK.bindHoverEvents();
          })
          .fail(app.ajaxError);

        rest.getFollowers({id: userId})
          .done(function (response) {
            $.each(response, function (index, val) {
              var template = $('#template-profile-social').html();
              var followerHtml = context.JK.fillTemplate(template, {
                userId: val.id,
                hoverAttributeId: "user-id",
                hoverAction: val.musician ? "musician" : "fan",
                avatar_url: context.JK.resolveAvatarUrl(val.photo_url),
                userName: val.name,
                location: val.location
              });

              $socialFollowers.append(followerHtml);
            });
            context.JK.bindHoverEvents();
          })
          .fail(app.ajaxError);
      }

      /****************** HISTORY TAB *****************/
      function renderHistory() {
        $aboutContent.hide();
        $historyContent.show();
        $bandsContent.hide();
        $socialContent.hide();
        $favoritesContent.hide();

        $('.profile-nav a.active').removeClass('active');
        $historyLink.addClass('active');

        bindHistory();
      }

      function bindHistory() {
        feed.refresh();
      }

      /****************** BANDS TAB *****************/
      function renderBands() {
        $bandsContent.empty();

        $aboutContent.hide();
        $historyContent.hide();
        $bandsContent.show();
        $socialContent.hide();
        $favoritesContent.hide();

        $('.profile-nav a.active').removeClass('active');
        $bandsLink.addClass('active');

        bindBands();
      }

      function bindBands() {

        rest.getBands({id: userId})
          .done(function (response) {
            if ((!response || response.length === 0) && isCurrentUser()) {
              var noBandHtml = $('#template-no-bands').html();
              $bandsContent.html(noBandHtml);
            }
            else {
              addMoreBandsLink();

              $.each(response, function (index, val) {
                var isBandMember = false;

                // build band member HTML
                var musicianHtml = '';
                if (val.musicians) {
                  for (var i = 0; i < val.musicians.length; i++) {
                    var musician = val.musicians[i];
                    var instrumentLogoHtml = '';
                    if (musician.instruments) {
                      for (var j = 0; j < musician.instruments.length; j++) {
                        var instrument = musician.instruments[j];
                        var inst = '/assets/content/icon_instrument_default24.png';
                        var toolTip = '';
                        if (instrument.instrument_id in instrument_logo_map) {
                          inst = instrument_logo_map[instrument.instrument_id].asset;
                          toolTip = instrument.instrument_id;
                        }
                        instrumentLogoHtml += '<img src="' + inst + '" title="' + toolTip + '" width="24" height="24" />&nbsp;';
                      }
                    }
                    if (!isBandMember)
                      isBandMember = musician.id === context.JK.currentUserId;

                    // this template is in _findSession.html.erb
                    var musicianTemplate = $('#template-musician-info').html();
                    musicianHtml += context.JK.fillTemplate(musicianTemplate, {
                      userId: musician.id,
                      avatar_url: context.JK.resolveAvatarUrl(musician.photo_url),
                      profile_url: "/client#/profile/" + musician.id,
                      musician_name: musician.name,
                      instruments: instrumentLogoHtml,
                      more_link: ''
                    });
                  }
                }
                var template = $('#template-profile-bands').html();
                var bandHtml = context.JK.fillTemplate(template, {
                  bandId: val.id,
                  biography: val.biography,
                  profile_url: "/client#/bandProfile/" + val.id,
                  band_edit_url: "/client#/band/setup/" + val.id + '/step0',
                  band_member_url: "/client#/band/setup/" + val.id + '/step4',
                  avatar_url: context.JK.resolveBandAvatarUrl(val.photo_url),
                  name: val.name,
                  location: val.location,
                  genres: formatGenres(val.genres),
                  follower_count: val.follower_count,
                  recording_count: val.recording_count,
                  session_count: val.session_count,
                  musicians: musicianHtml
                });

                $bandsContent.append(bandHtml);

                $('.profile-band-link-member-true').each(function (idx) {
                  isBandMember ? $(this).show() : $(this).hide();
                });
                $('.profile-band-link-member-false').each(function (idx) {
                  isBandMember ? $(this).hide() : $(this).show();
                });

                // wire up Band Follow button click handler
                configureBandFollowingButton(val.is_following, val.id);
              });

              if (response.length >= 3) {
                addMoreBandsLink();
              }
            }
            context.JK.bindHoverEvents();
          })
          .fail(app.ajaxError);
      }

      function addMoreBandsLink() {
        if (isCurrentUser()) {
          var moreBandsHtml = $('#template-more-bands').html();
          $bandsContent.append(moreBandsHtml);
        }
      }

      function formatGenres(genres) {
        var formattedGenres = '';
        if (genres) {
          for (var i = 0; i < genres.length; i++) {
            var genre = genres[i];
            formattedGenres += genre.description;
            if (i < genres.length - 1) {
              formattedGenres += ', ';
            }
          }
        }
        return formattedGenres;
      }

      function updateFriendCount(value) {
        if (!decrementedFriendCountOnce && !sentFriendRequest) {
          decrementedFriendCountOnce = true;
          var friendCount = $('#profile-friend-stats span.friend-count');
          friendCount.text(value + parseInt(friendCount.text()));
        }
      }

      function updateFollowingCount(value) {
        var $followingCount = $('#follower-stats span.follower-count');
        $followingCount.text(value + parseInt($followingCount.text()));
      }

      function updateBandFollowingCount(bandId, value) {
        var $bandFollowing = $('div[band-id="' + bandId + '"].profile-bands span.follower-count');
        $bandFollowing.text(value + parseInt($bandFollowing.text()));
      }

      function addBandFollowing(evt) {
        evt.stopPropagation();
        var bandId = $(this).parent().parent().parent().parent().attr('band-id');

        var newFollowing = {};
        newFollowing.band_id = bandId;

        rest.addFollowing(newFollowing)
          .done(function (response) {
            updateBandFollowingCount(bandId, 1); // increase counter
            configureBandFollowingButton(true, bandId);
            context.JK.GA.trackJKSocial(context.JK.GA.Categories.jkFollow, context.JK.GA.JKSocialTargets.band);
          })
          .fail(app.ajaxError);
      }

      function configureBandFollowingButton(following, bandId) {
        var $btnFollowBand = $('div[band-id=' + bandId + ']', '#bands-content').find('#btn-follow-band');
        $btnFollowBand.unbind("click");

        if (following) {
          $btnFollowBand.text('UNFOLLOW');
          $btnFollowBand.click(function (evt) {
            removeFollowing(true, bandId);
            evt.stopPropagation();
            return false;
          });
        } else {
          $btnFollowBand.text('FOLLOW');
          $btnFollowBand.click(addBandFollowing);
        }
      }

      /****************** FAVORITES TAB *****************/
      function renderFavorites() {
        $aboutContent.hide();
        $historyContent.hide();
        $bandsContent.hide();
        $socialContent.hide();
        $favoritesContent.show();

        $('.profile-nav a.active').removeClass('active');
        $favoritesLink.addClass('active');

        bindFavorites();
      }


      function bindFavorites() {
      }

      function initializeFeed() {

        var $scroller = $screen.find('.content-body-scroller#user-profile-feed-scroller');
        var $content = $screen.find('.feed-content#user-profile-feed-entry-list');
        var $noMoreFeeds = $screen.find('#user-profile-end-of-feeds-list');
        var $refresh = $screen.find('.btn-refresh-entries');
        var $sortFeedBy = $screen.find('#feed_order_by');
        var $includeDate = $screen.find('#feed_date');
        var $includeType = $screen.find('#feed_show');

        feed = new context.JK.Feed(app);
        feed.initialize($screen, $scroller, $content, $noMoreFeeds, $refresh, $sortFeedBy, $includeDate, $includeType, {time_range: 'all'});
      }

      function initialize(textMessageDialogInstance) {
        textMessageDialog = textMessageDialogInstance;
        var screenBindings = {
          'beforeShow': beforeShow,
          'afterShow': afterShow,
          'beforeHide': beforeHide
        };
        app.bindScreen('profile', screenBindings);
        events();
        initializeFeed();
        player = new context.JK.SoundCloudPlayerDialog(app);
      }

      this.initialize = initialize;
      this.beforeShow = beforeShow;
      this.afterShow = afterShow;
      return this;
    };

  })
(window, jQuery);