const CURRENT_LOCALE = chrome.i18n.getMessage('@@ui_locale');
const MULTIPART_FORMDATA_BOUNDARY = 'Google_Chrome_Screen_Capture';
const HIDE_ERROR_INFO_DELAY_TIME = 5000;

var UploadUI = {
  currentSite: '',
  uploading: false,
  sites: {},

  registerSite: function(id, siteObject) {
    this.sites[id] = siteObject;
  },

  getSiteObject: function(id) {
    return this.sites[id];
  },

  setUploading: function(state) {
    UploadUI.uploading = state;
  },

  init: function() {
    // Register supported site for image sharing.
    UploadUI.registerSite(SinaMicroblog.siteId, SinaMicroblog);
    UploadUI.registerSite(Facebook.siteId, Facebook);
    UploadUI.registerSite(Picasa.siteId, Picasa);
    UploadUI.registerSite(Imgur.siteId, Imgur);

    // Import style sheet for current locale
    if (CURRENT_LOCALE == 'zh_CN')
      UI.addStyleSheet('./i18n_styles/zh_CN_upload_image.css');
    else
      UI.addStyleSheet('./i18n_styles/en_US_upload_image.css');

    // Get i18n message
    i18nReplace('shareToSinaMicroblogText', SinaMicroblog.siteId +
      '_upload_header');
    i18nReplace('shareToFacebookText', Facebook.siteId + '_upload_header');
    i18nReplace('shareToPicasaText', Picasa.siteId + '_upload_header');
    i18nReplace('lastStep', 'return_to_site_selection');
    i18nReplace('closeUploadWrapper', 'close_upload_wrapper');
    i18nReplace('imageCaptionText', 'image_caption');
    i18nReplace('photoSizeTip', 'photo_size_tip');
    i18nReplace('shareToImgurText', Imgur.siteId + '_upload_header');
    $('requiredFlag').setAttribute('title',
      chrome.i18n.getMessage('invalid_caption'));

    // Add event listeners
    //$('btnUpload').addEventListener('click', UploadUI.showUploadWrapper, false);
    $('btnSave').addEventListener('click', UploadUI.saveImage, false);
    $('closeUploadWrapper').addEventListener('click',
      UploadUI.hideUploadWrapper, false);

    $('picasaBtn').addEventListener('click', function() {
      UploadUI.showUploadContentWrapper(Picasa.siteId);
    });
    $('facebookBtn').addEventListener('click', function() {
      UploadUI.showUploadContentWrapper(Facebook.siteId);
    }, false);
    $('sinaMicroblogBtn').addEventListener('click', function() {
      UploadUI.showUploadContentWrapper(SinaMicroblog.siteId);
    }, false);
    $('imgurBtn').addEventListener('click', function() {
      UploadUI.showUploadContentWrapper(Imgur.siteId);
    }, false);
    $('shareToOtherAccount').addEventListener('click', function() {
      var currentSite = UploadUI.currentSite;

      // Validate image description first
      if (UploadUI.validatePhotoDescription(currentSite)) {
        var callback = function() {
          var authenticationTip =
            chrome.i18n.getMessage('user_authentication_tip');
          UploadUI.showAuthenticationProgress(authenticationTip);
          UploadUI.getAccessToken(currentSite);
        };
        var users = Account.getUsers(currentSite);
        var numberOfUsers = Object.keys(users).length;

        // Logout when user has authenticated app
        if (numberOfUsers) {
          var logoutTip = chrome.i18n.getMessage('user_logout_tip');
          UploadUI.showAuthenticationProgress(logoutTip);
          var site = UploadUI.getSiteObject(currentSite);
          site.logout(callback);
        } else {
          callback();
        }
      }
    }, false);
    $('lastStep').addEventListener('click', UploadUI.showUploadSitesWrapper,
      false);
  },

  showUploadWrapper: function() {
    var uploadWrapper = $('uploadWrapper');
    UI.show(uploadWrapper);

    // Reset upload wrapper position
    var viewportWidth = window.innerWidth;
    var viewportHeight = window.innerHeight;
    var wrapperWidth = uploadWrapper.offsetWidth;
    var wrapperHeight = uploadWrapper.offsetHeight;

    var left = (viewportWidth - wrapperWidth) / 2;
    var top = (viewportHeight - wrapperHeight) / 3;
    left = left < 0 ? 0 : left;
    top = top < 0 ? 0 : top;

    var scrollTop = document.body.scrollTop;
    var scrollLeft = document.body.scrollLeft;

    UI.setStyle(uploadWrapper, {
      top: top + scrollTop + 'px',
      left: left + scrollLeft + 'px'
    });
    UploadUI.showUploadSitesWrapper();
    UploadUI.showOverlay();
  },

  hideUploadWrapper: function() {
    UI.hide($('uploadWrapper'));
    UploadUI.hideOverlay();
  },

  showOverlay: function() {
    var overlay = $('overlay');
    UI.setStyle(overlay, {
      width: document.body.scrollWidth + 'px',
      height: document.body.scrollHeight + 'px'
    });
    UI.show($('overlay'));
  },

  hideOverlay: function() {
    UI.hide($('overlay'));
  },

  updateUploadHeader: function(title) {
    $('uploadHeader').firstElementChild.firstElementChild.innerText = title;
  },

  showUploadSitesWrapper: function() {
    var uploadHeader = chrome.i18n.getMessage('upload_sites_header');
    UploadUI.updateUploadHeader(uploadHeader);
    UI.show($('uploadSitesWrapper'));
    UploadUI.hideUploadContentWrapper();
    UI.hide($('lastStep'));
  },

  hideUploadSitesWrapper: function() {
    UI.hide($('uploadSitesWrapper'));
  },

  showUploadContentWrapper: function(site) {
    UploadUI.currentSite = site;

    // Update upload wrapper UI
    var uploadHeader = chrome.i18n.getMessage(site + '_upload_header');
    UploadUI.updateUploadHeader(uploadHeader);
    UploadUI.hideUploadSitesWrapper();
    UploadUI.hideErrorInfo();
    UploadUI.hideAuthenticationProgress();
    UploadUI.clearPhotoDescription();
    UI.show($('uploadContentWrapper'));
    UI.show($('lastStep'));
    UploadUI.updateShareToOtherAccountText(site);
    UploadUI.togglePhotoDescriptionRequiredFlag(site);

    // Show authenticated accounts of current site
    UploadUI.clearAccounts();
    var users = Account.getUsers(site);
    for (var userId in users) {
      UploadUI.addAuthenticatedAccount(site, userId);
    }
  },

  hideUploadContentWrapper: function() {
    UI.hide($('uploadContentWrapper'));
  },

  clearPhotoDescription: function() {
    $('imageCaption').value = '';
  },

  validatePhotoDescription: function(site) {
    var caption = $('imageCaption');
    var invalidCaptionMsg = chrome.i18n.getMessage('invalid_caption');

    // Validate photo description
    if (site == SinaMicroblog.siteId && caption.value == '') {
      UploadUI.showErrorInfo(invalidCaptionMsg);
      caption.focus();
      return false;
    }
    return true;
  },

  togglePhotoDescriptionRequiredFlag: function(siteId) {
    if (siteId == SinaMicroblog.siteId)
      UI.show($('requiredFlag'));
    else
      UI.hide($('requiredFlag'));
  },

  updateShareToOtherAccountText: function(siteId) {
    var users = Account.getUsers(siteId);
    var userLength = Object.keys(users).length;
    if (userLength)
      i18nReplace('shareToOtherAccount', 'share_to_other_account');
    else
      i18nReplace('shareToOtherAccount', 'share_to_' + siteId + '_account');
  },

  showErrorInfo: function(text) {
    UI.show($('errorWrapper'));
    $('errorInfo').innerHTML = text;
    setTimeout(function() {
      UploadUI.hideErrorInfo();
    }, HIDE_ERROR_INFO_DELAY_TIME);
  },

  hideErrorInfo: function() {
    UI.hide($('errorWrapper'));
  },

  showProgressBar: function(accountId) {
    var progress = document.querySelector('#' + accountId +
      ' .progressBar');
    UI.show(progress);
  },

  hideProgressBar: function(accountId) {
    var progress = document.querySelector('#' + accountId +
      ' .progressBar');
    UI.hide(progress);
  },

  showAuthenticationProgress: function(title) {
    var progress = $('authenticationProgress');
    progress.setAttribute('title', title);
    UI.show(progress);
  },

  hideAuthenticationProgress: function() {
    UI.hide($('authenticationProgress'));
  },

  setProgress: function(accountId, loaded, total) {
    console.log('In setProgress, loaded: ' + loaded + ', total: ' + total);
    var progress = document.querySelector('#' + accountId + ' .progressBar');

    // One progress bar has 4 parts to represent progress
    var level = parseInt(loaded / total / 0.25);
    UI.setStyle(progress, 'background-position-y', '-' + (12 * level) + 'px');
  },

  showPhotoLink: function(accountId, link) {
    var photoLink = document.querySelector('#' + accountId + ' .photoLink');
    photoLink.setAttribute('href', link);
    UI.setStyle(photoLink, 'display', 'inline');
  },

  hidePhotoLink: function(accountId) {
    var photoLink = document.querySelector('#' + accountId + ' .photoLink');
    UI.hide(photoLink);
  },

  showUploadInfo: function(accountId, text) {
    var uploadInfo = document.querySelector('#' + accountId + ' .uploadInfo');
    uploadInfo.innerHTML = text;
    UI.show(uploadInfo);
  },

  hideUploadInfo: function(accountId) {
    var uploadInfo = document.querySelector('#' + accountId + ' .uploadInfo');
    UI.hide(uploadInfo);
  },

  clearAccounts: function() {
    $('uploadAccountList').innerHTML = '';
  },

  addAuthenticatedAccount: function(site, userId) {
    var template = $('accountItemTemplate').innerHTML;

    // Replace i18n message
    template = template.replace(/\$\{accountId\}/gi, site + '_' + userId);
    var shareToText = chrome.i18n.getMessage('share_to');
    template = template.replace(/\$\{accountName\}/gi,
      shareToText + ' ' + Account.getUser(site, userId)['name']);
    template = template.replace('${site}', site);
    template = template.replace('${userId}', userId);
    template = template.replace(/\$\{deletionTitle\}/gi,
      chrome.i18n.getMessage('deletion_title'));
    template = template.replace(/\$\{photoLinkText\}/gi,
      chrome.i18n.getMessage('photo_link_text'));
    template = template.replace(/\$\{progressInfo\}/gi,
      chrome.i18n.getMessage('progress_info'));

    // At most show 3 authenticated users
    var uploadAccountList = $('uploadAccountList');
    var accountsNumber = uploadAccountList.childElementCount;
    if (accountsNumber == 2) {
      uploadAccountList.removeChild(uploadAccountList.lastElementChild);
    }
    uploadAccountList.innerHTML = template + uploadAccountList.innerHTML;

    $('accountName').addEventListener('click', function(e) {
      UploadUI.upload(site, userId);
    });
    $('deleteBtn').addEventListener('click', function(e) {
      e.stopPropagation();
      UploadUI.deleteAccountItem(site + '_' + userId);
    });

    UploadUI.updateShareToOtherAccountText(site);
  },

  deleteAccountItem: function(accountId, noConfirm) {
    if (UploadUI.uploading && !noConfirm)
      return;
    var confirmText = chrome.i18n.getMessage('account_deletion_confirm');
    if (noConfirm || confirm(confirmText)) {
      $('uploadAccountList').removeChild($(accountId));

      // Clear localStorage
      var site = accountId.split('_')[0];
      var userId = accountId.split('_')[1];
      Account.removeUser(site, userId);
      UploadUI.updateShareToOtherAccountText(site);
    }
  },

  upload: function(siteId, userId) {
    if (UploadUI.uploading)
      return;

    // Initialize UI
    var accountId = siteId + '_' + userId;
    UploadUI.hideErrorInfo();
    UploadUI.hideUploadInfo(accountId);
    UploadUI.hidePhotoLink(accountId);
    if (!UploadUI.validatePhotoDescription(siteId))
      return;
    var caption = $('imageCaption').value;

    // Get ready for upload image.
    photoshop.draw();
    UploadUI.setUploading(true);
    UploadUI.showProgressBar(accountId);

    var site = UploadUI.getSiteObject(siteId);
    var user = Account.getUser(siteId, userId);
    var imageData = UploadUI.getImageData();
    var infoText;

    var callback = function(result, photoIdOrMessage) {
      if (result == 'success') {
        infoText = chrome.i18n.getMessage('get_photo_link');
        UploadUI.showUploadInfo(accountId, infoText);
        site.getPhotoLink(user, photoIdOrMessage, function(photoLinkResult,
                                                           photoLinkOrMessage) {
          if (photoLinkResult == 'success') {
            UploadUI.setUploading(false);
            UploadUI.hideUploadInfo(accountId);
            UploadUI.showPhotoLink(accountId, photoLinkOrMessage);
          } else {
            UploadUI.showErrorInfo(photoLinkOrMessage);
          }
        });
      } else {
        if (photoIdOrMessage == 'bad_access_token' ||
            photoIdOrMessage == 'invalid_album_id') {
          Account.removeUser(site.siteId, site.currentUserId);
          UploadUI.deleteAccountItem(accountId, true);
          UploadUI.getAccessToken(siteId);
        }
        UploadUI.setUploading(false);
        UploadUI.hideProgressBar(accountId);
        UploadUI.showErrorInfo(chrome.i18n.getMessage(photoIdOrMessage));
      }
      UploadUI.hideProgressBar(accountId);
    };

    if (user) {
      site.currentUserId = user.id;
      site.upload(user, caption, imageData, callback);
    } else {
      UploadUI.getAccessToken(siteId);
    }
  },

  getAccessToken: function(siteId) {
    var site = UploadUI.getSiteObject(siteId);
    var accessTokenCallback = function(result, userOrMessage) {
      if (result == 'success') {
        UploadUI.getUserInfo(siteId, userOrMessage);
      } else {
        // Show error information according to error reason
        UploadUI.showErrorInfo(chrome.i18n.getMessage(userOrMessage));
        UploadUI.hideAuthenticationProgress();
      }
    };

    site.getAccessToken(accessTokenCallback);
  },

  getUserInfo: function(siteId, user) {
    var site = UploadUI.getSiteObject(siteId);
    site.getUserInfo(user, function(result, userOrMessage) {
      if (result == 'success') {
        var userId = user.id;
        // Check if the authenticated user is added.
        if (!Account.getUser(siteId, userId)) {
          site.currentUserId = userId;
          Account.addUser(siteId, user);
          UploadUI.addAuthenticatedAccount(siteId, userId);
        }
        UploadUI.upload(siteId, userId);
      } else {
        var msg = chrome.i18n.getMessage(userOrMessage);
        UploadUI.showErrorInfo(msg);
      }
      UploadUI.hideAuthenticationProgress();
    });
  },

  getImageData: function() {
    var dataUrl = $('canvas').toDataURL('image/png');
    var imageDataIndex = dataUrl.indexOf('data:image/png;base64,');
    if (imageDataIndex != 0) {
      return;
    }

    // Decode to binary data
    return atob(dataUrl.substr(imageDataIndex + 22));
  },

  saveImage: function() {
    $('canvas').toBlob(function(blob) {
      console.log(chrome.extension.getBackgroundPage());
      saveAs(blob, chrome.extension.getBackgroundPage().screenshot.screenshotName+".png");
    });
  }
};

(function() {
// Cache tab id of edit page, so that we can get tab focus after getting access
// token.
var tabIdOfEditPage;
chrome.tabs.getSelected(null, function(tab) {
  tabIdOfEditPage = tab.id;
});

function selectTab(tabId) {
  chrome.tabs.update(tabId, {
    selected: true
  });
}

function closeTab(tabId) {
  chrome.tabs.remove(tabId);
}

function parseAccessToken(senderId, url, siteId) {
  var sites = UploadUI.sites;
  for (var id in sites) {
    var site = sites[id];
    if ((siteId && id == siteId) || site.isRedirectUrl(url)) {
      selectTab(tabIdOfEditPage);
      closeTab(senderId);
      site.parseAccessToken(url);
      return true;
    }
  }
  return false;
}

chrome.extension.onMessage.addListener(function(request, sender) {
  switch (request.msg) {
  case 'url_for_access_token':
    parseAccessToken(sender.tab.id, request.url, request.siteId);
    break;
  }
});
})();
