(function ($, window) {
    'use strict';

    // upload
    var upload = {
      el: '#upload-modal',
      url: '',
      server: '',
      trigger: '',
      type: '',
      items: [],
      init: function(){
        var that = this;
        this.setUrl = this.setUrl.bind(this);
        this.sortable = this.sortable.bind(this);
        this.sortable();
        // form processing
        $(document).on('click', '.form-validate input[type="submit"], #commentform input[type="submit"]', function (e) {
          var form = $(this).closest('form');
          that.validate(form);
        });

        $(document).on('click', '.btn-edit, .btn-upload', function(e){
            e.preventDefault();
            if(!play.is_user_logged_in) return;
            that.items = [];
            var id = $(this).closest('[data-play-id]').attr('data-play-id');
            $(that.el).remove();
            getModal(that.el, {name: 'upload_form', post_id: id}, that.sortable);
        });

        // remove
        $(document).on('click', '.track-list .remove', function (e) {
          var item = $(this).parent();
          item.remove();
          that.updateList();
        });
        
        // render image inline
        $(document).on('change', 'input[type="file"]', function(e){
          var input = $(this)[0];
          // show image inline
          if (input.files && input.files[0]) {
            var file = input.files[0];
            var img  = $(this).parent().find('img');
            if(img.length == 0) {
              img = $('<img>');
              $(this).next('.post-thumbnail').html(img);
            }
            try{
              var reader = new FileReader();
              reader.onload = function (e) {
                img.removeAttr('srcset');
                img.attr('src', e.target.result);
              };
              reader.readAsDataURL(file);
            }catch(e){}
          }
        });

        // online upload
        $(document).on('change', '[name="stream_url"]', function(e){
          if($(this).val().match(/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g)){
            that.url = $(this).val();
            $(that.el).remove();
            getModal(that.el, {name: 'upload_form', form: true}, that.setUrl);
            $(this).val('');
          }
        });

        // drag over
        $(document).on('dragover', '.dragdrop-upload', function (e) {
          e.stopPropagation();
          e.preventDefault();
          $(this).addClass('dropover');
        });

        // Drop upload
        $(document).on('drop', '.dragdrop-upload', function (e) {
          e.stopPropagation();
          e.preventDefault();
          $(this).removeClass('dropover');
          var items = e.originalEvent.dataTransfer.files;
          var files = [];
          var types = ['mp3','m4a','ogg','wav','mp4','m4v','mov','wmv','avi','mpg','ogv','3gp','3g2'];
          for (var i = items.length - 1; i >= 0; i--) {
            if( types.includes( items[i]['name'].split('.').pop() ) ){
              files.push( items[i] );
            }
          }
          if(files.length > 0){
            that.bulkUpload(files);
          }
        });

        // click upload
        $(document).on('change', '[name="stream_file"]', function(e){
          that.trigger = $(this);
          var files = $(this)[0].files;
          that.bulkUpload(files);
        });

        // change file
        $(document).on('change', '[name="upload_file"]', function(e){
          that.trigger = $(this);
          that.type = '';
          if($(this).attr('data-type') == 'single'){
            that.type = 'single';
          }
          var files = $(this)[0].files;
          var file = files[0];
          file.el = $(this).next('.progress');
          file['title'] = file['name'].replace(/\.[^/.]+$/, '').replace(/[\-_]/g, ' ');
          that.uploadFile( file );
        });

        // submit update
        $(document).on('click', '#upload [type="submit"]', function(e){
          e.preventDefault();
          var form = $(this).closest('form');
          var tracks = [];
          // get tracks
          if(that.items.length > 1){
            $('.track-list li').each(function(index){
              var _this = $(this),
              id = _this.attr('id'),
              item = that.getItem(id);
              tracks[index] = {};
              tracks[index].title = _this.find('input').val();
              if(item){
                tracks[index].url = item['url'];
                tracks[index].waveform = item['waveform'].join(',');
                tracks[index].metadata = item['metadata'];
              }
            });
            if(!that.getUploaded(that.items)){
              form.removeClass('processing');
              form.find('.file-uploading').show();
              return false;
            }
          }

          if(!that.validate(form)){ return false; };

          var data = new FormData(form[0]);

          if(tracks.length){
            data.append("tracks", JSON.stringify(tracks));
          }

          // upload
          $.ajax({
            url: play.rest.endpoints.upload,
            data: data,
            type: 'POST',
            processData: false,
            contentType: false,
            cache: false,
            beforeSend: function (xhr) {
              xhr.setRequestHeader('X-WP-Nonce', play.rest.nonce);
            }
          }).then(function (res) {
            if(res.status == 'success'){
              if(res.post.permalink){
                window.location = res.post.permalink;
              }
            }else if(res.status == 'error'){
              $('#upload').prepend('<div class="message"><p class="error">'+res.msg+'</p></div>');
            }
            form.removeClass('processing');
          });
          return false;
        });
      },
      bulkUpload: function(files){
        this.items = files;
        
        if(this.items.length > 1){
          this.type = 'multiple';
        }else{
          this.type = 'single';
        }
        this.upload = this.upload.bind(this);
        $(this.el).remove();
        getModal(this.el, {name: 'upload_form', form: true, type: (this.items.length > 1 ? 'playlist' : 'single') }, this.upload);
      },
      upload: function(){
        if(this.type == 'single'){
          $('.tracks').append('<ul class="track-list single"></ul>');
        }
        for (var i = this.items.length - 1; i >= 0; i--) {
          this.items[i]['id'] = i;
          this.items[i]['title'] = this.items[i]['name'].replace(/\.[^/.]+$/, '').replace(/[\-_]/g, ' ');
          this.items[i]['el'] = $('<li id="' + i + '" class="input"><div class="progress"><div class="progress-bar"></div></div><span class="handle"></span><input class="track-list-title" value="' + this.items[i]['title'] + '" /><span class="remove">×</span></div>');
          $('.track-list').append( this.items[i]['el'] );
          this.uploadFile(this.items[i], i);
        }
        this.sortable();
      },
      uploadFile: function(file){
        var that = this;
        // get waveform data
        var reader = new FileReader();
        reader.onload = function (event) {
          file['waveform'] = [];
          var audioContext = new (window.AudioContext || window.webkitAudioContext)();
          try{
            audioContext.decodeAudioData(event.target.result, function(buffer) {
              var wf = new Waveform();
              var data = wf.parsePeaks(buffer);
              file['waveform'] = data;
            });
          }catch(e){}
        };
        reader.readAsArrayBuffer(file);
        
        // upload file
        var data = new FormData();
        data.append("action", "upload_stream");
        data.append("file", file);
        data.append("frontend-upload-nonce", $('#frontend-upload-nonce').val());
        file['uploading'] = true;

        $.ajax({
          url: play.rest.endpoints.upload_stream,
          type: 'POST',
          data: data,
          processData: false,
          contentType: false,
          enctype: 'multipart/form-data',
          beforeSend: function (xhr) {
              xhr.setRequestHeader('X-WP-Nonce', play.rest.nonce);
          },
          xhr: function() {
            var xhr = $.ajaxSettings.xhr();
            if (xhr.upload) {
              xhr.upload.addEventListener("progress", function(evt) {
                if (evt.lengthComputable) {
                  var p = (evt.loaded / evt.total);
                  p = parseInt(p * 100);
                  if(file.el){
                    file.el.find('.progress-bar').css('width', p+'%');
                  }
                }
              }, false);
            }
            return xhr;
          }
        }).then(function (res) {
          if(file.el){
            file.el.find('.progress-bar').css('width', '0');
          }
          if (res.status == 'success') {
            file['url'] = res.url;
            file['metadata'] = res.metadata;
            that.setUpload(file);
          }else if(res.status == 'error'){
            if(res.data.errors.upload_error){
              var err = res.data.errors.upload_error;
              if( typeof err !== 'string' ){
                err = err.join(', ');
              }
              $('#upload').prepend('<div class="message"><p>'+file.name+'</p><p class="error">'+err+'</p></div>');
            }
          }
        }).always(function(){
          file['uploading'] = false;
          if(that.items.length > 1 && that.getUploaded(that.items)){
            $('.file-uploading').hide();
            $('.file-uploaded').show();
          }
        });
      },
      getUploaded: function(items){
        var uploaded = true;
        for (var i = items.length - 1; i >= 0; i--) {
          if(items[i]['uploading']){
            uploaded = false;
          }
        }
        return uploaded;
      },
      setUpload: function(item){
        // set url
        if( this.trigger && this.trigger.parent().hasClass('file-upload') ){
          this.trigger.parent().prev('input').val( item.url );
        }

        if( this.type == 'single' ){
          var form = $('.form');
          form.find('[name="title"]').val(item.title);
          form.find('[name="stream"]').val(item.url);

          if(item.metadata['title']){
            form.find('[name="title"]').val(item.metadata['title']);
          }

          if(item.metadata['length_formatted']){
            form.find('[name="duration"]').val(item.metadata['length_formatted']);
          }

          if(item.metadata['artist']){
            form.find('[name="artist"]').val(item.metadata['artist']);
          }

          if(item.waveform.length){
            form.append('<input type="hidden" name="waveform" value="'+item.waveform.join(',')+'" />');
          }

        }else{
          if(item.metadata['title']){
            item.el.find('.track-list-title').val(item.metadata['title']);
          }
        }

      },
      getItem: function(id){
        for(var i=0; i<this.items.length; i++){
          if( parseInt(this.items[i].id) === parseInt(id) ){
              return this.items[i];
          }
        }
      },
      validate: function(form){
        var valid = true;
        form.find('[required]').each(function(){
          if(!$.trim($(this).val())){
              $(this).focus();
              valid = false;
              return false;
          }else{
              valid = true;
          }
        });
        if(valid){
          form.addClass('processing');
        }
        return valid;
      },
      setUrl: function(){
        var _this = this;
        $('[name="stream"]').val(_this.url);
        playImport(_this.url, {}, function(data){
          var WF = new Waveform();
          data.title && $('[name="title"]').val(data.title);
          data.description && $('[name="content"]').val(data.description);
          data.duration && $('[name="duration"]').val( WF.msToTime( data.duration ) );
          data.tags && $('[name="tag"]').val(data.tags);

          if( data.stream_url ){
            $('[name="upload"]').append('<input type="hidden" name="stream_url" value="'+ data.stream_url +'"/>');
          }
          if( data.waveform_data ){
            $('[name="upload"] [name="waveform"]').remove();
            $('[name="upload"]').append('<input type="hidden" name="waveform" value="'+ data.waveform_data +'"/>');
          }
          if( data.blob ){
            var container = new DataTransfer();
            container.items.add(data.blob);
            $('.file-upload input[name="image"]')[0].files = container.files;
            if( data.artwork_url ){
              $('.file-upload img').attr('src', data.artwork_url);
              $('.file-upload input').removeAttr('required');
            }
          }
        });
      },
      sortable: function(){
        var that = this;
        $('.track-list').length && sortable('.track-list', {handle: '.handle'})[0].addEventListener('sortupdate', function(e) {
          that.updateList();
        });
      },
      updateList: function(){
        var items = $('.track-list li[id]').map(function() { return this.id; }).get();
        $('[name="post"]').val( items.join() );
      },
      import: function(url, obj, callback){
        var server = '';
        if( url.indexOf('soundcloud.com') !== -1 ){
          server = 'soundcloud';
          url = (play.proxy ? play.proxy : 'https://proxy-server.herokuapp.com/') + url;
        }
        if( url.indexOf('hearthis.at') !== -1 ) {
          server = 'hearthis';
          url = url.replace( 'https://hearthis.at/', 'https://api-v2.hearthis.at/' );
        }

        url.match(/(http:|https:|)\/\/(player.|www.|music.|m.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/);
        if( RegExp.$3.indexOf('youtu') > -1 ) {
          server = 'youtube';
          url = 'https://www.googleapis.com/youtube/v3/videos?id='+ RegExp.$6 +'&key='+ play.youtube_api_key +'&part=snippet,contentDetails,statistics,status';
        }
        if( RegExp.$3.indexOf('vimeo') > -1 ) {
          server = 'vimeo';
          url = 'https://vimeo.com/api/v2/video/'+ RegExp.$6 +'.json';
        }

        obj.url = url;
        $.ajax(obj)
        .then(function(data){
          if( $.isArray(data) ){
            data = data[0];
          }
          if(server == 'soundcloud'){
            var m = data.match(/window\.__sc_hydration = (.*);<\/script>/);
            if(m){
              var n = eval(m[1]);
              for(var i=0; i<n.length; i++){
                if( n[i].hydratable === 'sound' ){
                  data = n[i].data;
                  //data.stream_url = data.uri;
                  var tags = data.tag_list.match(/\w+|"[^"]+"/g);
                  if(tags){
                    data.tags = tags.join(',').replaceAll('"','');
                  }
                }
              }
            }
          }
          if(server == 'hearthis'){
            data.duration = data.duration * 1000;
          }
          if(server == 'soundcloud'){
            data.artwork_url = data.artwork_url.replace('-large', '-t500x500');
          }
          if(server == 'vimeo'){
            data.duration = data.duration * 1000;
            data.artwork_url = data.thumbnail_large;
          }
          var WF = new Waveform();
          if(server == 'youtube'){
            if(data['items']){
              var item = data['items'][0];
              var url = '//img.youtube.com/vi/' + item.id + '/';
              data.title = item.snippet.title;
              data.description = item.snippet.description;
              data.artwork_url = item.snippet.thumbnails.maxres ? url+'maxresdefault.jpg' : url+'sddefault.jpg';
              data.duration = WF.timeToMS( item.contentDetails.duration );
              data.tags = item.snippet.tags;
            }
          }

          if(callback){
            data.type = 'single';
            callback(data);
          }

          // save youtube and soundwave thumbnail
          if( data.artwork_url ){

            var xhr = new XMLHttpRequest();
            xhr.onload = function() {
                var reader = new FileReader();
                reader.onloadend = function() {
                  var res = reader.result.split(',');
                  var base64Image = res[1].replace(/\s/g, '');
                  var type = res[0].split(':')[1].split(';')[0];
                  var binaryImg = atob(base64Image);

                  var n = binaryImg.length;
                  var u8arr = new Uint8Array(n);
                  while (n--) {
                    u8arr[n] = binaryImg.charCodeAt(n);
                  }
                  var name = data.title +'.'+ data.artwork_url.split('.').pop();
                  var file = new File([u8arr], name, {type: type});

                  var obj = {};
                  obj.blob = file;
                  obj.artwork_url = data.artwork_url;

                  if(callback) callback( obj );
                }
                reader.readAsDataURL(xhr.response);
            };
            xhr.open('GET', data.artwork_url);
            xhr.responseType = 'blob';
            xhr.send();
          };

          // soundcloud and hearthis waveform data
          if(data.waveform_url){
            var obj = {};
            var url = data.waveform_url.replace('.png', '.json');
            var d = [];
            if(data.waveform_data){
              url = data.waveform_data;
            }
            obj.url = url;
            $.ajax(obj).then(function(data){
              var obj = {};
              if(data.samples){
                // soundcloud
                d = data.samples;
              }else{
                // hearthis. failed 
                d = eval( data );
              }
              obj.waveform_data = WF.resizeData(d, WF.options.waveLength);
              if(callback){
                callback(obj);
              }
            });
          }

        });
      },
    }
    upload.init();

    window.playImport = upload.import;

    // search
    var timeoutID = null;
    $(document).on('keyup', '#header-search-form input, .search-form input', function(e){
      var $input = $(this);
      if($input.val().length < 3) return;
      $input.parent().addClass('search-loading');
      clearTimeout(timeoutID);
      timeoutID = setTimeout(function() { search($input); }, 1000); 
    });
    function search(input) {
      var dropdown = input.parent().find('.dropdown-menu');
      var query = input.val();
      $.ajax({
          url : play.rest.endpoints.search,
          datatype: 'json',
          type: 'get',
          data:{
            search: query
          },
          beforeSend: function() {
            dropdown.html('');
          }
      }).then( function( data ) {
          var el = '';
          $.each(data, function(k, v){
            el += '<a class="dropdown-item '+ (v.type == 'user' ? 'dropdown-user' : '') +'" href="'+v.url+'">'+v.thumbnail+'<span><span>'+v.title+'</span><span class="author">'+v.author+'</span></span></a>'
          });
          input.parent().removeClass('search-loading');
          dropdown.append(el);
          dropdown.dropdown('show');
          $(document).trigger('refresh');
      });
    }

    // comment
    if (typeof EventTarget !== "undefined") {
        var func = EventTarget.prototype.addEventListener;
        EventTarget.prototype.addEventListener = function (type, fn, capture) {
            this.func = func;
            if(typeof capture !== "boolean"){
                capture = capture || {};
                capture.passive = false;
            }
            this.func(type, fn, capture);
        };
    };
    $(document).on('click', '#commentform #submit', function(e){
        //e.preventDefault();
        var that = $(this),
            form = that.closest('#commentform'),
            comment = $('#comment').val(),
            status = $('<div class="comment-message"></div>');
        if($.trim(comment) == ''){
          return false;
        }
        form.find('.comment-message').remove();
        status.insertBefore('.comment-form-comment');
        
        that.prop('disabled', true);
        var data = form.serialize();
        var url = form.attr('action');

        $.ajax({
            type: 'post',
            url: url,
            data: data,
            error: function(jqXHR, textStatus, errorThrown){
               var res = jqXHR.responseText;
               var error = res.match(/<body id="error-page">([\s\S^<]*?)<\/body>/);
               form.find('.comment-message').html('').append( error[0] ).addClass('error');
               that.prop('disabled', false);
            }
        }).then(
          function(data, textStatus, jqXHR){
            that.prop('disabled', false);
            var error = data.match(/<body id="error-page">([\s\S^<]*?)<\/body>/);
            if(error){
                form.find('.comment-message').html('').append( error[0] ).addClass('error');
            }else{
                $(document).trigger( 'reload', ['', window.location.href.replace(window.location.hash,'')+'#comments'] );
            }
          }
        );
        return false;
    });

    // popper
    var popper = null;
    var popper_el = 'dropdown-more';

    function destory_popper(){
      if (popper) {
        popper.destroy();
        popper = null;
      }
    }

    // more
    $(document).on('click', '.btn-more', function (e) {
      e.preventDefault();
      e.stopPropagation();
      destory_popper();

      var $id = $(this).closest('[data-play-id]').attr('data-play-id') || $(this).attr('data-id');
      var $dp = $('#'+popper_el);
      if($dp.length > 0){
        $dp.attr('data-play-id', $id);
        $dp.html(play.el_more);
      }else{
        $dp = $('<div id="'+popper_el+'" class="dropdown-menu" data-window data-play-id="'+ $id +'">'+play.el_more+'</div>');
        $('body').append($dp);
      }

      $dp.find('.btn-share').attr('data-url', $(this).attr('data-url')).attr('data-embed-url', $(this).attr('data-embed-url'));

      var btns = $dp.find('.btn-edit, .btn-remove');
      if(play.is_user_logged_in && $(this).attr('data-editable') == 'true'){
        btns.each(
          function(){
            var url = play.edit_url + $id+'&action='+$(this).attr('data-action');
            $(this).attr('data-url', url);
          }
        );
      }else{
        btns.remove();
      }
      if($(this).attr('data-album') == 'true'){
        $dp.find('.btn-playlist').remove();
      }
      if($(this).attr('data-playable') == 'false'){
        $dp.find('.btn-next-play, .btn-queue, .btn-play-now, .dropdown-divider').remove();
      }
      if($(this).attr('data-type') == 'user'){
        $dp.find('.btn-playlist').remove();
        $dp.find('.btn-next-play, .btn-queue, .btn-play-now').attr('data-user-id', $id);
      }
      
      popper = new Popper($(this), $dp, {
        modifiers: {
          preventOverflow: { enabled: true },
        },
      });

      $dp.addClass('show');
    });
  
    // dismiss popper
    $(document).on('click', function (e) {
      destory_popper();
      $('#'+popper_el).removeClass('show');
    });

    // delete account
    $(document).on('click', '.btn-delete-account', function(e){
        e.preventDefault();
        getModal('#remove-modal', {name:'delete-account'});
    });

    // btn like/follow
    $(document).on('click', '.btn-like, .btn-follow', function(e) {
      e.preventDefault();
      var $this = $(this),
          id = $this.attr('data-id'),
          action = $this.attr('data-action'),
          type = $this.attr('data-type');
      $this.attr('disabled', 'disabled');
      $.ajax({
        url: play.rest.endpoints[action],
        datatype: 'json',
        type: 'get',
        data: {
          type: type,
          action: action,
          nonce : play.nonce,
          id : id,
          url: location.href
        },
        beforeSend: function (xhr) {
            xhr.setRequestHeader('X-WP-Nonce', play.rest.nonce);
        }
      }).then(
        function(data){
          $this.attr('disabled', false);
          if(data.error){
            if(data.url){
              //location.href = data.url;
            }
          }else{
            var el = $('[data-id="'+id+'"][data-action="'+action+'"][data-type="'+type+'"]');
            if(data.status == 1){
              el.addClass('active');
            }else{
              el.removeClass('active');
            }
            $this.find('.count').text(data.count);
            // trigger data
            $(document).trigger(action+'.play', [id, data.status, data.type]);
          }
        }
      );
    });
    
    // login
    var login = {
      el: '#login-form',
      el_msg: '.message',
      btn: null,
      action: 'login',
      init: function(){
            var that = this;
            this.showForm = this.showForm.bind(this);
            $(document).on('click', '.btn-like, .btn-playlist, .btn-follow, .btn-ajax-login, .btn-ajax-register, .btn-ajax-login a, .btn-ajax-register a', function(e){
                e.preventDefault();
                if(play.is_user_logged_in) return;
                if($('.is-single '+that.el).length > 0){
                  $(that.el+ ' input:first').focus();
                  return;
                }
                that.action = ($(this).hasClass('btn-ajax-register') || $(this).parent().hasClass('btn-ajax-register')) ? 'register' : 'login';
                getModal('#login-modal', {name: 'login_form'}, that.showForm);
            });
            that.initEvents();
      },
      initEvents: function(){
          var that = this;
          // switch form
          $(document).on('click', that.el+' a[class*="btn-"]', function(e){
              var target = $($(this).attr('data-target'));
              if(target.length > 0){
                e.preventDefault();
                $(that.el_msg, that.el).html('');
                $(that.el+' form').hide();
                target.show();
              }
          });
          
          // submit form
          $(document).on('click', that.el+' input[type="submit"]', function(e){
              e.preventDefault();
              that.btn = $(this);
              that.ajaxForm();
          });
      },
      ajaxForm: function(){
          var that = this;
          
          var form = $(that.btn).closest('form'), valid = true;
          var redirect_to = form.find('[name="redirect_to"]').val();
          $(that.el_msg, that.el).html('');
          
          form.find('input[type="text"], input[type="password"], input[type="email"], [required]').each(function(){
              var input = $(this);
              if(input.attr('name') == 'user_login'){
                var val = input.val().toLowerCase();
                input.val(val);
              }
              if(!$.trim(input.val())){
                  input.focus();
                  valid = false;
                  return false;
              }else{
                  valid = true;
              }
          });
          if(!valid) return false;
          form.addClass('processing');
          that.btn.prop('disabled', true);
          var formData = new FormData(form[0]);
          $.ajax({
              url: form[0].action,
              data: formData,
              type: 'POST',
              processData: false,
              contentType: false,
              cache: false
          }).then(function (res) {
              form.removeClass('processing');
              that.btn.prop('disabled', false);
              var error = res.match(/<div id="login_error">([\s\S^<]*?)<\/div>/);
              var msg = res.match(/<p class="message">([\s\S^<]*?)<\/p>/);;
              if(error){
                  $(that.el_msg, form).first().append( error[0] );
                  return;
              }else if(msg){
                  $(that.el_msg, form).first().append( msg[0] );
              }
              //
              redirect_to && (window.location = redirect_to);
          });
      },
      showForm: function(){
          $('[data-target="#'+this.action+'form"]').trigger('click');
      }
    }
    login.init();
    
    // playlist
    var playlist = {
        id: 0,
        data: [],
        el: '#playlist-modal',
        btn: null,
        link: '',
        init: function(){
          var that = this;
          this.r = this.r.bind(this);
          this.setLink = this.setLink.bind(this);
          // add playlist modal to body
          $(document).on('click', '.btn-playlist', function(e){
            e.preventDefault();
            if(!play.is_user_logged_in) return;
            that.id = $(this).closest('[data-play-id]').attr('data-play-id');
            getModal(that.el, {name:'playlist'}, that.r);
            $(that.el).find('form').show();
          });

          // new playlist
          $(document).on('click', that.el+' .btn-new', function(e){
              e.preventDefault();
              that.btn = $(this);
              that.c();
          });

          // remove playlist
          $(document).on('click', that.el+' .btn-remove', function(e){
              e.preventDefault();
              that.btn = $(this);
              that.d();
          });

          // update
          $(document).on('click', that.el+' .btn-add, '+ that.el+' .btn-added', function(e){
              e.preventDefault();
              that.btn = $(this);
              that.u();
          });

          // dismiss modal
          $(document).on('click', that.el+' a', function(e){
            $(e.target).closest('.modal').modal('hide');
          });

          // remove
          $(document).on('click', '.btn-remove', function(e){
              e.preventDefault();
              that.link = $(this).attr('data-url');
              getModal('#remove-modal', {name:'remove'}, that.setLink);
          });
          
        },
        c: function(){
          var that = this,
              form = $(that.el).find('form'),
              title = form.find('input');
          if($.trim(title.val()) == ''){
            return;
          }
          that.btn.prop('disabled', 'disabled');
          $.ajax({
            type : "GET",
            dataType : "json",
            url : play.rest.endpoints.playlist,
            data : {nonce: play.nonce, post_id: that.id, title: title.val(), type: 'c'},
            beforeSend: function (xhr) {
                xhr.setRequestHeader('X-WP-Nonce', play.rest.nonce);
            }
          }).then(function( res ) {
            that.data.unshift(res.data);
            form.hide();
            that.btn.prop('disabled', false);
            title.val('');
            that.render();
          });
        },
        r: function(){
          var that = this;
          $.ajax({
            type : "GET",
            dataType : "json",
            url : play.rest.endpoints.playlist,
            data : {nonce: play.nonce, post_id: that.id, type: 'r'},
            beforeSend: function (xhr) {
                xhr.setRequestHeader('X-WP-Nonce', play.rest.nonce);
            }
          }).then(function(data){
            if(data.status == 'success'){
              that.data = data.data;
              that.render();
            }
          });
        },
        u: function(){
          var that = this,
              $id  = that.btn.closest('[data-play-id]').attr('data-play-id'),
              $obj = that.getObj($id, that.data);

          that.btn.prop('disabled', 'disabled');

          if(that.btn.is('.btn-add')){
            $obj['post'].push(that.id);
          }else{
            $obj['post'].splice( $.inArray(that.id, $obj['post']), 1);
          }
          
          $.ajax({
            type : "GET",
            dataType : "json",
            url : play.rest.endpoints.playlist,
            data : {nonce: play.nonce, post_id: $id, post: $obj['post'], type: 'u'},
            beforeSend: function (xhr) {
                xhr.setRequestHeader('X-WP-Nonce', play.rest.nonce);
            }
          }).then(function( res ) {
            that.btn.prop('disabled', false);
            if(res.status == 'success'){
              that.render();
            }
          });
        },
        d: function(){
          var that = this,
              $id  = that.btn.closest('[data-play-id]').attr('data-play-id');
              
          that.btn.prop('disabled', 'disabled');
          
          $.ajax({
            type : "GET",
            dataType : "json",
            url : play.rest.endpoints.playlist,
            data : {nonce: play.nonce, post_id: $id, type: 'd'},
            beforeSend: function (xhr) {
                xhr.setRequestHeader('X-WP-Nonce', play.rest.nonce);
            }
          }).then(function( data ) {
            that.btn.prop('disabled', false);
            if(data.status == 'success'){
              $.each(that.data, function( index, value ) {
                if($id == that.data[index]['id']){
                  that.data.splice( index, 1);
                  return false;
                }
              });
              that.render();
            }
          });
        },
        render: function(){
          var that = this,
              els = $(that.el+' .block-loop-row');
          els.empty();
          $.each(that.data, function(index, value){
            var item = $('#tpl-item').clone();
            item.attr('id', '').attr('style', '');
            item.attr('data-play-id', value['id']);
            value['thumb'] && item.find('img').attr('src', value['thumb']);
            item.find('.entry-title').html( value['title'] ).attr('href', value['url']);
            item.find('.entry-count').html( value['post'].length );
            item.find('.post-thumbnail a').attr('href', value['url']);

            if( $.inArray( that.id, value['post'] ) !== -1 ){
              item.find('.btn-add').hide();
              item.find('.btn-added').show();
            }else{
              item.find('.btn-added').hide();
              item.find('.btn-add').show();
            }
            $(els).append(item);
          });
          $(document).trigger('refresh');
        },
        getObj: function(key, objs){
          var $obj = false;
          $.each(objs, function( index, value ) {
            if(key == objs[index]['id']){
              $obj = objs[index];
              return;
            }
          });
          return $obj;
        },
        setLink: function(){
          $('[data-remove]').attr('href', this.link);
        }
    }
    playlist.init();

    // share
    var share = {
        el: '#share-modal',
        el_embed: '.share-embed',
        link: '',
        embed: '',
        init: function(){
          var that = this;
          this.setUrl = this.setUrl.bind(this);
          $(document).on('click', '.btn-share', function(e){
              var iframe = $(that.el_embed).find('iframe');
              if(iframe.length > 0){
                var code = iframe[0].outerHTML;
                iframe.remove();
                $(that.el_embed).append(code);
              }
              
              that.link = $(this).attr('data-url') || $(this).parent().prev().attr('data-url');
              that.embed = $(this).attr('data-embed-url');
              if(!that.link){
                that.link = location.href;
              }
              getModal(that.el, {name:'share'}, that.setUrl, that.close);
          });
        },
        setUrl: function(){
          var that = this;
          $('.share-list a').each( function(index) {
            $(this).attr( 'href', $(this).attr('data-url') + encodeURIComponent( that.link ) );
          });
          $('#share-url').val( that.link );
          $('.share-embed iframe').attr( 'src', that.embed );
          $('#embed-code').val( $('.share-embed iframe')[0].outerHTML );
        },
        close: function(){
          $('.share-embed iframe').attr( 'src', ' ' );
        }
    }
    share.init();

    // notification
    var notification = {
        inter: play.rest.timeout,
        _inter: null,
        el: '#dropdown-notification',
        init: function(){
          this.initEvent();
        },
        initEvent: function(){
          var _this = this;
          $(document).on('click', _this.el, function(e){
            _this.getNotification();
          });
          if(!play.is_user_logged_in) return;
          _this.inter = setInterval( function(){
            _this.getNotification();
          }, _this.inter);
        },
        getNotification: function() {
          var _this = this;
          $.ajax({
            url : play.rest.endpoints.notification,
            type : "GET",
            beforeSend: function (xhr) {
                xhr.setRequestHeader('X-WP-Nonce', play.rest.nonce);
            }
          }).then(function(res){
            $('.dropdown-notification-list').html(res.content);
            $(document).trigger('refresh');
            if($(res).find('.is-new').length > 0){
              $(_this.el).addClass('has-new');
            }else{
              $(_this.el).removeClass('has-new');
            }
          });
        }
    }
    notification.init();

    var getModal = function(modal, data, callback, closeCallback){
      if(!$(modal).length){
        var m = $('<div class="modal fade modal-loading" id="'+modal.substr(1)+'"><div class="modal-dialog"><div class="modal-content"><div class="modal-body"><div class="spinner"></div></div></div></div></div>');
        $('body').append(m);
        var url = play.rest.endpoints.modal;
        $.ajax({
            type : "GET",
            url : url,
            data : data,
            beforeSend: function (xhr) {
                xhr.setRequestHeader('X-WP-Nonce', play.rest.nonce);
            }
        }).then(function(res){
            if(res){
                m.removeClass('modal-loading').find('.modal-content').html(res.content);
                if(callback){
                  callback();
                }
            }else{
                $(modal).modal('hide');
            }
        });
      }else{
        if(callback){
          callback();
        }
      }
      $(modal).modal('show');
      $(modal).on('hidden.bs.modal', function (e) {
        if(closeCallback){
          closeCallback();
        }
      })
    }

})(jQuery, window);
