/**
 * NBC_KaUploader
 * 
 * Responsible for image upload.
 * Note: NBC_KaMediaSubmitter submits the upload form.
 * 
 * Example (see test_upload in cms):
 * 
  upload.init({
    iframeId:'uploadBtnRemote',
    iframeLocation:'/test/upload/iframe/',
    uploadToPending: false,
    onComplete: function(result) {
      U.log("onComplete called");
      U.log("pathToMedia: [" + result.pathToMedia + "] mediaType: [" + result.mediaType + "]"); 
      $("#photoLoading").hide();          
      if (result.mediaType == "PHOTO") {
        $("#imagePreview").attr({src: result.pathToMedia});      
      }
    },
    onReset: function() {
      U.log("onReset called");
      $("#imagePreview").attr({src: ''});            
    },
    onLookupStart: function() {
      U.log("onLookupStart called");
      $("#photoLoading").show();
    },
    onLookupError: function() {
      U.log("onLookupError called");
      $("#photoLoading").hide();      
      $("#imagePreview").attr({src: nbc.mediaDomain + "/designimages/txt_moment_error_photo.gif"});      
    }    
  });
 *
 */
var NBC_KaUploader = function() {
  // static variables
  NBC_KaUploader.retryMax = 5;
  NBC_KaUploader.MEDIA_BASE = "http://media.kickstatic.com/kickapps/images/";
  NBC_KaUploader.userId;
  NBC_KaUploader.userToken;
  NBC_KaUploader.userName;
  
  /**
   * Options for the upload util. 
   * 
   * @required 
   * @param iframeLocation  - relative url to the iframe
   * @param iframeId        - id of the iframe element 
   * @param iframeParentFieldId - id of the parent field where the iframe will be added
   * @param requireLogin - (true|false) wether to force user login
   * 
   * @optional
   * @param category        - category to be placed in, ie, "New York/Moment"; defaults to "City Name" 
   * @param isProfileImage  - (T|F) whether this is a profile image upload; defaults to non-profile
   * @param uploadToPending - (true|false) whether to put this image in pending queue; defaults to false - active (auto approved)
   * @param skipRetrieval   - whether to skip the retrieval; defaults to false
   * @param defaultUID      - if requireLogin is false, the user id to use if no user is logged in
   * @param defaultToken    - if requireLogin is false, the user token to use if no user is logged in
   * @param defaultUser     - if requireLogin is false, the user name to use if no user is logged in
   * 
   * @callbacks
   *  onLookupStart       - called after the form has been submitted and search to get the pathToMedia started
   *  onComplete(result)  - called after upload is complete; result contains "pathToMedia" and "mediaType" attributes
   *  onReset             - called after the upload form is reset
   *  onLookupError       - called after it could not find the media
   */
  var init = function(options) {
    var self = this;
    if (!options) {
      throw new Error("Invalid initialization for upload.")
    }
    
    if (!options.iframeLocation || !options.iframeId || !options.iframeParentFieldId) {
      throw new Error("Invalid initialization for upload.")
    }
    
    self.config = options;
    
    // provide defaults
    if (!options.category) {
      self.config.category = nbc.cityName;
    }    
    if (!options.isProfileImage) {
      self.config.isProfileImage = 'F';
    }
    self.config.pendingStatus = "active";
    if (options.uploadToPending) {
      U.log("Setting mode to [pending]");
      self.config.pendingStatus = "pending";
    }
    
    self.result = {}; // just initialize
    
    U.log("uploader: Setting iframe location to " + self.config.iframeLocation);    
  };
  
  var displayUpload = function() {
    if (this.config.requireLogin && !NBC_UserOverlay.validateLogin()) {
      return;
    }
    
    document.getElementById(this.config.iframeParentFieldId).innerHTML = "<iframe id='" + this.config.iframeId + "' src='" + this.config.iframeLocation + "' marginheight='0' marginwidth='0' frameborder='0' scrolling='no'></iframe>";
    this.resetUpload({startListening:true});        
  };
  
  var startPost = function() {    
    if(this.config.loadingGraphic){
        var loadingGraphic = document.getElementById(this.config.loadingGraphic);
        loadingGraphic.style.display = 'block';
    }
    if(this.config.successMessage){
        var successMsg = document.getElementById(this.config.successMessage);
        successMsg.style.display = 'none';
    }
    
    if(this.config.requireLogin){
      NBC_KaUploader.userId = user.userId;
      NBC_KaUploader.userName = user.userName;
      NBC_KaUploader.userToken = user.token;
    } else {
      NBC_KaUploader.userId = this.config.defaultUID;
      NBC_KaUploader.userToken = this.config.defaultToken;
      NBC_KaUploader.userName = this.config.defaultUser;
    }
    var uploadId = "Media from [" + NBC_KaUploader.userName + "] uploaded on [" + new Date().toDateString() + " " + new Date().toLocaleTimeString() + "]";
    var msg = '{action:"add",uploadId:"' + uploadId + '",token:"' + NBC_KaUploader.userToken + 
        '",category:"' + this.config.category + '",isProfileImage:"' + 
        this.config.isProfileImage + '",pendingStatus:"' + this.config.pendingStatus + '"}';      
    var targetFrame = document.getElementById(this.config.iframeId);    
    U.log("uploader: Sending an upload msg [" + msg + "] to iframe id [" + this.config.iframeId + "] at [" + this.config.iframeLocation + "] " + typeof targetFrame);
    targetFrame.contentWindow.location = this.config.iframeLocation + "#" + msg; // all browsers
    targetFrame.contentWindow.focus();
//  targetFrame.contentWindow.postMessage(msg, nbc.fullDomain); // IE8 and FF only
    
    this.hideUploadFrame();
    
    if (!this.config.skipRetrieval) {
      // reset temp variables
      this.retryCount = 0; 
      this.retryPreviewCount = 0;
      this.found = false;
      this.photoInserted = false;
      
      if (typeof this.config.onLookupStart === "function") {
        this.config.onLookupStart();
      }
      else {
        U.log("WARN! onLookupStart is not defined");
      }      
     
      if (this.config.uploadToPending) {
        this.lookupMediaInPendingQueue(uploadId);
      }
      else {
        this.lookupMediaInUserUpdates(uploadId);      
      }
    }
    else {
      this.uploadFinished();
    }  
  };
  
  var uploadFinished = function() {
    if (typeof this.config.onComplete === "function") {
      this.config.onComplete(this.result);
    }
    else {
      U.log("uploader: WARNING! onComplete is not a function in the config");
    }
  };
  
  var showUploadFrame = function() {
    $('#' + this.config.iframeParentFieldId).fadeIn();
  };
  
  var hideUploadFrame = function() {
    $('#' + this.config.iframeParentFieldId).fadeOut();
  };  
  
  var resetUpload = function(options) {
    var self = this;
    U.log("uploader: Resetting media upload...");
    if (typeof self.config.onReset === "function") {
      self.config.onReset();
    }
    U.eraseCookie("ka_upload"); 
    self.stopRequested = true; // stop listening for user action
    $("#" + self.config.iframeId)[0].src = self.config.iframeLocation;
    if (options && options.startListening) {
      self.stopRequested = false;        
      self.waitForUploadRequest();
    }
    self.showUploadFrame();
  };
  
  var lookupMediaInUserUpdates = function(name) {
    var self = this;
    U.log("uploader: Looking for [" + name + "]...");
    if (!self.found) {
      var queryString = "action=getMostRecentUpdate&uid=" + NBC_KaUploader.userId + "&r=" + Math.random();
      jQuery.ajax({
        url: "/i/dispatcher/?h=user",
        data: queryString,
        type: 'GET',
        dataType: 'json',
        success: function(data) {
          if (typeof data.status !== "undefined" &&  data.status == 1) {
            U.log("uploader: First media is [" + data.firstItem.title + "]...");
            if (data.firstItem.title.indexOf(name) >= 0) {
              self.found = true;
              var mediaDetail = extractMediaDetail(data.firstItem);
              if (mediaDetail.mediaType == "PHOTO") {
                self.photoFound(mediaDetail);
              }
              else {
                self.videoFound(mediaDetail);
              }
            }
          }
          else if (typeof data.profile !== "undefined" && data.profile.status == -1) {
            U.log("uploader: WARNING: error returned: " + data.profile.error);
          }
        },
        complete: function() {
          if (!self.found && self.retryCount < NBC_KaUploader.retryMax) {
            U.log("uploader: Media not found. Retrying...");
            setTimeout(function() {
              self.lookupMediaInUserUpdates(name);
            }, 8000);
            self.retryCount++;
          }              
          else if (!self.found && self.retryCount >= NBC_KaUploader.retryMax) {
            self.mediaNotFound();
          }
        }
      });
    }
  };

  var lookupMediaInPendingQueue = function(name) {
    var self = this;
    U.log("uploader: Looking for pending media [" + name + "]...");
    if (!self.found) {
      var queryString = "action=lookupPendingMedia&title=" + name + "&r=" + Math.random();
      jQuery.ajax({
        url: "/i/dispatcher/?h=user",
        data: queryString,
        type: 'GET',
        dataType: 'json',
        error: function(xhr, text, error) {
          U.log("Error [" + text + "]");
        },
        success: function(data) {
          if (typeof data.status !== "undefined" &&  data.status == 1) {
            U.log("uploader: Found media!");
            self.found = true;
            if (data.mediaType == "PHOTO") {
              self.photoFound(data);
            }
            else {
              self.videoFound(data);
            }         
          }
        },
        complete: function() {
          if (!self.found && self.retryCount < NBC_KaUploader.retryMax) {
            U.log("uploader: Media not found. Retrying...");
            setTimeout(function() {
              self.lookupMediaInPendingQueue(name);
            }, 8000);
            self.retryCount++;
          }              
          else if (!self.found && self.retryCount >= NBC_KaUploader.retryMax) {
            self.mediaNotFound();
          }
        }
      });
    }
  };

  /**
   * Given
   * <title>Photo - Moment photo Tuesday, July 14, 2009 3:19:38 PM</title>
   * <link>http://affiliate.kickapps.com/service/displayMediaPlayPage.kickAction?mediaType=PHOTO&amp;mediaId=4528264&amp;as=67525&amp;b=</link>
   * extract mediaId and compose {pathToMedia:"67525/photos/PHOTO_4528293_67525_5087968_main.jpg"}
   * 
   * VIDEO
   * <title>Video - Media from [sk] uploaded on [Fri Oct 02 2009 11:55:51 AM]</title>
   * <link>http://affiliate.kickapps.com/service/displayMediaPlayPage.kickAction?mediaType=VIDEO&amp;mediaId=801797&amp;as=67525&amp;b=
   */
  var extractMediaDetail = function(rssItem) {
    var mediaId,
      siteId,
      mediaType;
    U.log("uploader: Extracting details from [" + rssItem.link + "]");
    var linkParams = rssItem.link.split("?")[1];
    var splitArr = linkParams.split("&");
    for (var i = 0; i < splitArr.length; i++) {
      var nameValueArr = splitArr[i].split("=");
      if (nameValueArr.length == 2) {
        if (nameValueArr[0] == "mediaId") {
          mediaId = nameValueArr[1];
        }
        else if (nameValueArr[0] == "as") {
          siteId = nameValueArr[1];
        }
        else if (nameValueArr[0] == "mediaType") {
          mediaType = nameValueArr[1];
        }
      }
    }
    if (mediaId && siteId && mediaType) {
      if (mediaType == "VIDEO") {
        pathToMedia = mediaId + "/" + siteId; 
      }
      else if (mediaType == "PHOTO") {
        pathToMedia = siteId + "/photos/PHOTO_" + mediaId + "_" + siteId + "_" + NBC_KaUploader.userId + "_main.jpg";
      }
      else {
        throw new Error("Uploader encountered an unsupported media type [" + mediaType  + "]");
      }
      return {pathToMedia:pathToMedia,mediaId:mediaId,mediaType:mediaType};
    }
    else {
      U.log("Could not parse mediaId nor siteId");
      return {};
    }
  };
    
  var videoFound = function(media) {
    var self = this;
    var pathToMedia = NBC_KaUploader.MEDIA_BASE + media.pathToMedia;
    var payload = '                                                                                                                        ' +
      '[DO NOT EDIT - CUSTOM_CODE [VIDEO - urlStart[' +  pathToMedia + ']urlEnd VIDEO_END] CUSTOM_CODE_END]';
    self.result.payload = payload;
    self.result.pathToMedia = pathToMedia;
    self.result.mediaType = media.mediaType;
    U.log("uploader: Video payload: " + payload);
    if(self.config.payloadFieldId){
      $("#"+this.config.payloadFieldId).val(payload);
    }
    self.uploadFinished();
  };
  
  var photoFound = function(media) {
    var self = this;
    var pathToMedia = NBC_KaUploader.MEDIA_BASE + media.pathToMedia;

    if (!self.photoInserted) {
      // Insert preloaded image after it finishes loading
      $('<img />')
        .attr('src', pathToMedia)
        .load(function(){
          self.result.pathToMedia = pathToMedia;
          self.result.mediaType = media.mediaType;
          self.photoInserted = true;
          var payload = '                                                                                                                        ' +
            '[DO NOT EDIT - CUSTOM_CODE [PHOTO - urlStart[' +  pathToMedia + ']urlEnd PHOTO_END] CUSTOM_CODE_END]';
          self.result.payload = payload;
          U.log("uploader: Photo payload: " + payload);
          if(self.config.payloadFieldId){
            U.log("PayloadField:"+self.config.payloadFieldId);
            $("#"+self.config.payloadFieldId).val(payload);
          }
          self.uploadFinished();
      });
      
      if (!self.photoInserted && self.retryPreviewCount < 10) {
        U.log("uploader: Having trouble loading [" + pathToMedia + "]... retry #" + self.retryPreviewCount);
        // let's check in a few secs
        setTimeout(function() {
          if (!media.pathToMediaOrig) {
            media.pathToMediaOrig = media.pathToMedia;
          }
          media.pathToMedia = media.pathToMediaOrig + "?r=" + Math.random();
          self.photoFound(media);
        }, 5000);
        self.retryPreviewCount++;
      }
      
      if (self.retryPreviewCount == 10) {
        self.mediaNotFound();
        throw new Error("Image upload failed.");
      }
    }
  };

  var mediaNotFound = function() {
    U.log("Media not found!");
    if (typeof this.config.onLookupError === "function") {
      this.config.onLookupError();
    }
    else {
      U.log("WARN: onLookupError is not defined in the config!");
    }
  };
  
  var waitForUploadRequest = function() {
    U.log("... waiting ... ")
    var self = this;
    if (U.readCookie("ka_upload") == "yes") {
      self.startPost();
      U.eraseCookie("ka_upload");
    }
    else {
      if (!self.stopRequested) {
        setTimeout(function() {
          self.waitForUploadRequest();
        }, 500);      
      }
    }
  }

  /* PUBLIC METHODS */
  return {
    init: init,
    displayUpload: displayUpload,
    startPost: startPost,
    showUploadFrame: showUploadFrame,
    resetUpload: resetUpload,
    waitForUploadRequest: waitForUploadRequest,
    hideUploadFrame: hideUploadFrame,
    lookupMediaInUserUpdates: lookupMediaInUserUpdates,
    lookupMediaInPendingQueue: lookupMediaInPendingQueue,
    photoFound: photoFound,
    videoFound: videoFound,
    mediaNotFound: mediaNotFound,
    uploadFinished: uploadFinished
  }; 
};
