$ = jQuery
context = window
logger = context.JK.logger
rest = new context.JK.Rest()

@AvatarStore = Reflux.createStore(
  {

    listenables: @AvatarActions
    selection: null
    updatingAvatar: false
    targetCropSize: 88
    largerCropSize: 200
    currentFpfile: null
    signedCurrentFpfile: null

    init: ->
      this.listenTo(context.AppStore, this.onAppInit)

    onAppInit: (@app) ->

    onStart: (target, type) ->
      logger.debug("AvatarStore start", target.id, type)
      @target = target
      @type = type

      @selection = null
      @updatingAvatar = false

      @currentFpfile = @determineCurrentFpfile();
      @currentCropSelection = @determineCurrentSelection(@target);
      @signedCurrentFpFile = null
      @changed()
      @signFpfile()

      @app.layout.showDialog('upload-avatar')

    onSelect: (selection) ->
      @selection = select
      @changed()

    onPick: () ->

      if @type == 'school'
        genpolicy = rest.generateSchoolFilePickerPolicy({id: @target.id})
      else if @type == 'retailer'
        genpolicy = rest.generateRetailerFilePickerPolicy({id: @target.id})

      genpolicy.done((filepickerPolicy) =>
        @pickerOpen = true
        @changed()
        window.filepicker.setKey(gon.fp_apikey);
        window.filepicker.pickAndStore({
          mimetype: 'image/*',
          maxSize: 10000*1024,
          policy: filepickerPolicy.policy,
          signature: filepickerPolicy.signature
        }, { path: @createStorePath(@target), access: 'public'  },
          (fpfiles) => (
            @pickerOpen = false
            @afterImageUpload(fpfiles[0]);
          ),
          (fperror) => (
            @pickerOpen = false
            @changed()

            if fperror.code != 101 # 101 just means the user closed the dialog
              alert("unable to upload file: " + JSON.stringify(fperror))

          )
        )
      )
      .fail(@app.ajaxError)

    afterImageUpload: (fpfile) ->
      logger.debug("afterImageUploaded", typeof fpfile, fpfile)
      $.cookie('original_fpfile', JSON.stringify(fpfile));

      @currentFpfile = fpfile
      @signedCurrentFpfile = null
      @currentCropSelection = null
      @changed()
      @signFpfile()

    signFpfile: () ->
      if @type == 'school'
        genpolicy = rest.generateSchoolFilePickerPolicy({id: @target.id})
      else if @type == 'retailer'
        genpolicy = rest.generateRetailerFilePickerPolicy({id: @target.id})

      genpolicy.done((policy) => (
        @signedCurrentFpfile = @currentFpfile.url + '?signature=' + policy.signature + '&policy=' + policy.policy;
        @changed()
      ))

    getState: () ->
      {
        target: @target,
        type: @type,
        selection: @selection,
        updatingAvatar: @updatingAvatar,
        currentFpfile: @currentFpfile,
        currentCropSelection: @currentCropSelection,
        signedCurrentFpfile: @signedCurrentFpfile
      }

    changed: () ->
      state = @getState()
      logger.debug("change: ", state)
      @trigger(state)

    onSelect: (event) ->
      @selection = event;


    delete: () ->

    update: () ->

    getPolicy: () ->


    updateAvatarSuccess: (response) ->
      $.cookie('original_fpfile', null)

      @target = response

      # notify any listeners that the avatar changed
      # userDropdown.loadMe();
      # $('.avatar_large img').trigger('avatar_changed', [self.userDetail.photo_url]);
      # $(document).triggerHandler(EVENTS.USER_UPDATED, response);
      @app.notify({   title: "Logo Updated", text: "You have updated your avatar successfully." }, null, true);

      if @type == 'school'
        window.SchoolActions.refresh()
      if @type == 'retailer'
        window.RetailerActions.refresh()

      @app.layout.closeDialog('upload-avatar')


  #  retrieves a file that has not yet been used as an avatar (uploaded, but not cropped)
    getWorkingFpfile: () ->
      return JSON.parse($.cookie('original_fpfile'))


    createStorePath: (target) ->
      gon.fp_upload_dir + '/' + @type + '/' + target.id + '/'


    createOriginalFilename: (target) ->
      #  get the s3
      if target.original_fpfile
        fpfile =  JSON.parse(target.original_fpfile)
      else
        fpfile = null
      return 'original_avatar.jpg'



    determineCurrentFpfile: () ->
      #precedence is as follows:
      #  * tempOriginal: if set, then the user is working on a new upload
      # * storedOriginal: if set, then the user has previously uploaded and cropped an avatar
      # * null: neither are set above

      tempOriginal = @getWorkingFpfile()
      if @target.original_fpfile
        storedOriginal = JSON.parse(@target.original_fpfile)
      else
        storedOriginal = null

      if tempOriginal
        tempOriginal
      else
        storedOriginal

    determineCurrentSelection: (target) ->
      #  if the cookie is set, don't use the storage selection, just default to null
      if $.cookie('original_fpfile') == null
        result = target.crop_selection
      else
        result = null

      if result?
        JSON.parse(result)
      else
        null

    onDelete: () ->
      if @updatingAvatar
        return

      @updatingAvatar = true
      @changed()

      if @type == 'school'
        rest.deleteSchoolAvatar({id: @target.id}).done((response) => @deleteDone(response)).fail((jqXHR) => @deleteFail(jqXHR))
      else if @type == 'retailer'
        rest.deleteRetailerAvatar({id: @target.id}).done((response) => @deleteDone(response)).fail((jqXHR) => @deleteFail(jqXHR))

    deleteDone: (response) ->
      @currentFpfile = null
      @signedCurrentFpfile = null
      @updatingAvatar = false
      @selection = null
      @currentCropSelection = null
      if @type == 'school'
        window.SchoolActions.refresh()
      else if @type == 'retailer'
        window.RetailerActions.refresh()

      @app.layout.closeDialog('upload-avatar');

      @changed()

    deleteFail: (jqXHR) ->
      $.cookie('original_fpfile', null)
      @currentFpfile = null
      @signedCurrentFpfile = null
      @selection = null
      @updatingAvatar = false
      @currentCropSelection = null
      @changed()
      @app.ajaxError(jqXHR)
    onUpdate: () ->
      if @updatingAvatar
        return

      if @selection?
        @updatingAvatar = true
        @changed()
        currentSelection = @selection
        logger.debug("Converting...");
        fpfile = @determineCurrentFpfile();

        if @type == 'school'
          genpolicy = rest.generateSchoolFilePickerPolicy({ id: @target.id, handle: fpfile.url, convert: true })
        else if @type == 'retailer'
          genpolicy = rest.generateRetailerFilePickerPolicy({ id: @target.id, handle: fpfile.url, convert: true })

        genpolicy.done((filepickerPolicy) =>
          window.filepicker.setKey(gon.fp_apikey)
          window.filepicker.convert(fpfile, {
            crop: [
              Math.round(currentSelection.x),
              Math.round(currentSelection.y),
              Math.round(currentSelection.w),
              Math.round(currentSelection.w)],
            fit: 'crop',
            format: 'jpg',
            quality: 90,
            policy: filepickerPolicy.policy,
            signature: filepickerPolicy.signature
          }, { path: @createStorePath(@target) + 'cropped-' + new Date().getTime() + '.jpg', access: 'public' },
            (cropped) => (@scale(cropped))
          )
        )
      else
        @app.notify( {   title: "Upload an Avatar First", text: "To update your avatar, first you must upload an image using the UPLOAD button"}, null, true);

    scale: (cropped) ->
      logger.debug("converting cropped");

      if @type == 'school'
        genpolicy = rest.generateSchoolFilePickerPolicy({id: @target.id, handle: cropped.url, convert: true})
      else if @type == 'retailer'
        genpolicy = rest.generateRetailerFilePickerPolicy({id: @target.id, handle: cropped.url, convert: true})

      genpolicy.done((filepickerPolicy) => (
        window.filepicker.convert(cropped, {
            height: @targetCropSize,
            width: @targetCropSize,
            fit: 'scale',
            format: 'jpg',
            quality: 75,
            policy: filepickerPolicy.policy,
            signature: filepickerPolicy.signature
          },  { path: @createStorePath(@target), access: 'public' },
          (scaled) => (@scaledLarger(scaled, cropped, filepickerPolicy)),
          (fperror) => (@handleFpError(fperror)))
      ))
      .fail(@app.ajaxError)

    scaledLarger: (scaled, cropped, filepickerPolicy) ->
      window.filepicker.convert(cropped, {
        height: @largerCropSize,
        width: @largerCropSize,
        fit: 'scale',
        format: 'jpg',
        quality: 75,
        policy: filepickerPolicy.policy,
        signature: filepickerPolicy.signature
      },  { path: @createStorePath(@target) + 'large.jpg', access: 'public' },
        (scaledLarger) => (@updateServer(scaledLarger, scaled, cropped)),
        (fperror) => (@handleFpError(fperror))
      )

    updateServer: (scaledLarger, scaled, cropped) ->
      logger.debug("converted and scaled final image %o", scaled);
      if @type == 'school'
        update = rest.updateSchoolAvatar({
          id: @target.id,
          original_fpfile: @determineCurrentFpfile(),
          cropped_fpfile: scaled,
          cropped_large_fpfile: scaledLarger,
          crop_selection: @selection
        })
      else if @type == 'retailer'
        update = rest.updateRetailerAvatar({
          id: @target.id,
          original_fpfile: @determineCurrentFpfile(),
          cropped_fpfile: scaled,
          cropped_large_fpfile: scaledLarger,
          crop_selection: @selection
        })

      update.done((response) => @updateAvatarSuccess(response))
      .fail(@app.ajaxError)
      .always(() => (
        @updatingAvatar = false
        @changed()
      ))

    handleFpError: (fperror) ->
      alert("unable to scale larger selection. error code: " + fperror.code);
      @updatingAvatar = false;
      @changed()

  }
)
