require 'rubyXL'
class Admin::CustomGalleriesController < OrbitAdminController
  include Admin::CustomGalleriesHelper
  before_filter :setup_vars
  before_action :authenticate_user, :except => "imgs"
  before_action :log_user_action
  layout :compute_layout
  find_tag = Tag.all.select{|value| value.name==I18n.t('custom_gallery.not_show_desc')}
  if find_tag.length==0
    module_app_id = ModuleApp.where(:key=>"custom_gallery").first[:_id]
    tags = ModuleApp.where(:key=>"custom_gallery").first.tags
    tag0 = Tag.new(is_default: false,module_app_ids: [module_app_id])
    tag1 = Tag.new(is_default: false,module_app_ids: [module_app_id])
    nowlocale = I18n.locale
    I18n.available_locales.each do |locale|
      I18n.locale = locale
      tag0.name = I18n.t('custom_gallery.show_desc')
      tag1.name = I18n.t('custom_gallery.not_show_desc')
    end
    I18n.locale = nowlocale
    tag0.save
    tag1.save
    tags << tag0
    tags << tag1
  elsif find_tag.length>1
    show_tags = Tag.all.select{|value| value.name==I18n.t('custom_gallery.show_desc')}
    show_tags.each_with_index do |show_tag,index1|
      if index1>0
        if show_tag.taggings.count==0
          show_tag.delete
        end
      end
    end
    find_tag.each_with_index do |not_show_tag,index1|
      if index1>0
        if not_show_tag.taggings.count==0
          not_show_tag.delete
        end
      end
    end
  end
  def compute_layout
    if action_name== 'index' && !params['page_no'].nil?
      false
    else
      'back_end'
    end
  end
  def get_tag
    custom_album = CustomAlbum.find(params['ele_id']) rescue nil
    if !custom_album.nil?
      text =  custom_album.tags.collect do |tag|
                "<li class=\"label\"> #{tag.name}</li>"
              end.join
      render :text => text
    else
      render :text => ''
    end
  end
  def rotate_images
    begin
      image_ids = params['image_ids'].split(',')
      count = image_ids.count
      rot_ang = params[:rotate_angle].to_i
      variable = CustomAlbumVariable.first
      if variable.nil?
        variable = CustomAlbumVariable.new
      end
      variable.finish = false
      variable.save!
      Thread.new do
        variable = CustomAlbumVariable.first
        image_ids.each_with_index do |image_id,index|
          image = CustomAlbumImage.find(image_id) rescue nil
          next if image.nil?
          if !(image.custom_album_crops.first.nil?)
            w_and_h = image.file.get_w_and_h
            cords = image.custom_album_crops.map{|v| [[v.crop_x.to_f,v.crop_y.to_f],
                                              [v.crop_x.to_f,v.crop_y.to_f+v.crop_h.to_f],
                                              [v.crop_w.to_f+v.crop_x.to_f,v.crop_y.to_f],
                                              [v.crop_w.to_f+v.crop_x.to_f,v.crop_y.to_f+v.crop_h.to_f]]}[0]
            rot_diff = rot_ang/90
            if (rot_diff) % 2 == 1
              new_w = (w_and_h[1]).to_f
              new_h = (w_and_h[0]).to_f
            else
              new_w = (w_and_h[0]).to_f
              new_h = (w_and_h[1]).to_f
            end
            
            rot_times = rot_diff % 4
            deg = (90.0*rot_times/180*Math::PI)
            cords = cords.collect do |cord|
              x = cord[0]-w_and_h[0].to_f/2
              y = cord[1]-w_and_h[1].to_f/2
              [x*Math.cos(deg)-y*Math.sin(deg)+new_w/2,x*Math.sin(deg)+y*Math.cos(deg)+new_h/2]
            end
            all_x = cords.collect do |cord|
              cord[0]
            end
            all_y = cords.collect do |cord|
              cord[1]
            end
            image.custom_album_crops.first.update_attributes(crop_x: all_x.min,crop_y: all_y.min,crop_w: all_x.max - all_x.min,crop_h: all_y.max - all_y.min)
          end
          variable.progress_percent = (index*100.0/count).floor.to_s+'%'
          image.file.rotate_ang(rot_ang)
          all_version = image.file.versions.map{|k,v| k}
          begin
            variable.progress_filename = image[:file].to_s
            all_version.each do |version|
                if !(version.to_s == 'resized' && crop_but_no_backup(image)) 
                    image.file.recreate_versions! version
                    image.save!
                end
            end
          rescue => e
            variable.progress_filename = e.inspect.to_s
            puts e.inspect
          end
          variable.save!
        end
        variable.finish = true
        variable.save!
    end
    rescue => e
        puts e.inspect
    end
    redirect_to :controller=> 'images' ,:action => 'crop_process'
  end
  
  def save_crop
    begin
      images = CustomAlbumImage.where(:id.in => Array(params[:id]))
      x = params['x']
      y = params['y']
      w = params['w']
      h = params['h']
      cords = x.zip(y,w,h)
      count = cords.length
      variable = CustomAlbumVariable.first
      if variable.nil?
        variable = CustomAlbumVariable.new
      end
      variable.finish = false
      variable.save!
      Thread.new do
        variable = CustomAlbumVariable.first
          image_ids= images.pluck(:id)
          image_ids.each_with_index do |image_id,index|
            image = CustomAlbumImage.find(image_id)
            cord = cords[index]
            if image.custom_album_crops.first.nil?
                image.custom_album_crops.create(crop_x: cord[0],crop_y: cord[1],crop_w: cord[2],crop_h: cord[3])
            else
                image.custom_album_crops.first.update_attributes(crop_x: cord[0],crop_y: cord[1],crop_w: cord[2],crop_h: cord[3])
            end
            variable.progress_percent = (index*100.0/count).floor.to_s+'%'
            all_version = image.file.versions.map{|k,v| k}
            begin
                #org_fname = image.file.path
                #org_extname = File.extname(org_fname)
                #org_fname.slice! org_extname
                #FileUtils.cp(org_fname + org_extname, org_fname + '_resized' + org_extname)
                variable.progress_filename = image[:file].to_s
                all_version.each do |version|
                    if !(version.to_s == 'resized' && crop_but_no_backup(image)) 
                        image.file.recreate_versions! version
                        image.save!
                    end
                end
            rescue => e
                variable.progress_filename = e.inspect.to_s
                puts e.inspect
            end
            variable.save!
        end
        variable.finish = true
        variable.save!
    end
    rescue => e
        puts e.inspect
    end
    redirect_url = "/admin/custom_galleries/crop_process"
    render :json => {'href' => redirect_url}.to_json
  end
  def call_translate
    text = params['text']
    render :json => {'translate' => "#{t(text.to_s)}" }.to_json
  end
  def recreate_image
    notalive =  ((CustomAlbumVariable.first.notalive.nil? ? true : CustomAlbumVariable.first.notalive) rescue true)
    if notalive
      if !params['custom_album_id'].to_s.empty?
        variable = CustomAlbumVariable.first
        if variable.nil?
          variable = CustomAlbumVariable.new
        end
        variable.finish = false
        variable.save!
        choice_ids = params['custom_album_id'].split(',')
        custom_albums = CustomAlbum.where(:id.in => choice_ids)
        if !(params['use_default']=='true')
          color = params['color_choice'].to_s.empty? ? 'transparent' : params['color_choice']
          custom_albums.each do |custom_album|
            if custom_album.custom_album_colors.first.nil?
              custom_album.custom_album_colors.create('color' => color)
            else
              custom_album.custom_album_colors.first.update_attributes('color' => color, 'updated_at' => Time.now)
            end
          end
        end
        count = custom_albums.reduce(0){|x,i| i.custom_album_images.count+x}
        Thread.new do
          i = 0
          custom_album_ids = custom_albums.pluck(:id)
          custom_album_ids.each do |custom_album_id|
            custom_album = CustomAlbum.find(custom_album_id) rescue CustomAlbum.new()
            custom_album_image_ids = custom_album.custom_album_images.pluck(:id)
            custom_album_image_ids.each do |image_id|
              image = CustomAlbumImage.find(image_id)
              error = nil
              all_version = image.file.versions.map{|k,v| k}
              begin
                all_version.each do |version|
                  if !(version.to_s == 'resized' && crop_but_no_backup(image)) 
                      image.file.recreate_versions! version
                      image.save!
                  end
                end
              rescue => error
              end
              variable = CustomAlbumVariable.first
              variable.progress_percent = (i*100.0/count).floor.to_s+'%'
              if !error.nil?
                  variable.progress_filename = error.inspect.to_s.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?')
                  sleep(1)
              else
                  variable.progress_filename = image[:file].to_s
              end
              variable.save!
              i+=1
            end
          end
          variable = CustomAlbumVariable.first
          variable.finish = true
          variable.save!
        end
      else
        variable = CustomAlbumVariable.first
        variable.finish = true
        variable.progress_filename = ''
        variable.progress_percent = '100%'
        variable.save!
      end
    end
  end
  def finish_recreate
    variable = CustomAlbumVariable.first
    variable.progress_percent = '0%'
    variable.progress_filename = ''
    variable.notalive = true
    variable.save!
    render :text => ''
  end
  def recreate_progress
    progress_percent = CustomAlbumVariable.first.progress_percent rescue '0%'
    progress_filename = CustomAlbumVariable.first.progress_filename rescue ''
    finish = CustomAlbumVariable.first.finish rescue false
    render :json => {'percent' => progress_percent, 'filename' => progress_filename, 'finish' => finish }.to_json
  end
  def filter_custom_album
    @tags = @module_app.tags
    categories = @module_app.categories.enabled
    @filter_fields = filter_fields(categories, @tags)
    @filter_fields.delete(:status)
    custom_albums1 = CustomAlbum.where(:order.in => [nil,-1]).desc(:created_at).with_categories(filters("category")).with_tags(filters("tag"))
    custom_albums1 = search_data(custom_albums1,[:name])
    custom_albums2 = CustomAlbum.all.where(:order.ne=>-1).and(:order.ne=>nil).asc(:order).with_categories(filters("category")).with_tags(filters("tag"))
    custom_albums2 = search_data(custom_albums2,[:name])
    @fiter_custom_albums = custom_albums1.concat(custom_albums2)
  end
  def update_custom_album_setting
    if params[:custom_album_setting_limit]
      params_custom_album_setting = {:limit=>params[:custom_album_setting_limit]}
    else
      params_custom_album_setting = params.require(:custom_album_setting).permit!
    end
    CustomAlbumSetting.first.update_attributes(params_custom_album_setting)
    redirect_to '/admin/custom_galleries'
  end
  def setting
    @custom_album_setting = CustomAlbumSetting.first
  end
  def index
    custom_album_length = CustomAlbum.where(:custom_module=>params[:custom_module],:bind_uid=>params[:bind_uid]).count
    custom_album_sort = CustomAlbum.where(:custom_module=>params[:custom_module],:bind_uid=>params[:bind_uid]).asc(:created_at)
    if (custom_album_sort.first.custom_album_colors.first.nil? rescue false)
      custom_album_sort.each_with_index do |custom_album|
        if custom_album.custom_album_colors.first.nil?
            custom_album.custom_album_colors.create('color' => 'transparent')
        end
      end
    end
    @url = request.original_fullpath
    @limit_count = CustomAlbumSetting.first.limit.to_i
    @limit_count = custom_album_length if @limit_count == 0
    if params['page_no'].nil?
      @show_script = true 
      @custom_albums = filter_custom_album.take @limit_count
    else
      @show_script = false 
      start = (params['page_no'].to_i - 1)*@limit_count
      @custom_albums = filter_custom_album[start...start+@limit_count]
    end
    if CustomAlbumColor.count!=0
      if CustomAlbumColor.all.desc('updated_at').first[:color] == 'transparent'
          @color_save = ''
      else
          @color_save = CustomAlbumColor.desc('updated_at').first[:color]
      end
    else
        @color_save = 'transparent'
    end
    @custom_album_configs = CustomAlbumConfig.all
    if request.xhr?
      render :partial => "custom_albums"
    elsif params[:custom_module].blank? || params[:bind_uid].blank?
      render "display_enable_modules"
    end
  end

  def show
    @custom_album = CustomAlbum.find(params[:id])
    @images = @custom_album.custom_album_images.where(:order.in => [nil,-1]).desc(:created_at)
    images = @custom_album.custom_album_images.where(:order.gt => -1).asc(:order)
    @images = @images.concat(images)
    image_content = []
    @images.each do |image|
      image_content << {"id" => image.id.to_s,"title"=> image.title_translations, "description" => image.description_translations,"tags" => image.tags.collect{|t| t.id.to_s}}
    end
    @tags = @module_app.tags
    @photos_data = {"custom_galleries" => image_content}.to_json
  end

  def new
    @custom_album = CustomAlbum.new
    @tags = @module_app.tags
    @categories = @module_app.categories
  end

  def create
    custom_album = CustomAlbum.new(custom_album_params)
    custom_album.save!
    custom_module = custom_album.custom_module
    bind_uid = custom_album.bind_uid
    if custom_module.present?
      redirect_to admin_custom_galleries_path + "/#{custom_module}#{bind_uid.present? ? ('-'+bind_uid) : ''}"
    else
      redirect_to admin_custom_galleries_path
    end
  end

  def destroy
    custom_album = CustomAlbum.find(params[:id])
    custom_module = custom_album.custom_module
    bind_uid = custom_album.bind_uid
    custom_album.destroy
    if custom_module.present?
      redirect_to admin_custom_galleries_path + "/#{custom_module}#{bind_uid.present? ? ('-'+bind_uid) : ''}"
    else
      redirect_to admin_custom_galleries_path
    end
  end

  def edit
      @custom_album = CustomAlbum.find(params[:id])
      if can_edit_or_delete?(@custom_album)
        @tags = @module_app.tags
        @categories = @module_app.categories
      else
        render_401
      end
  end

  def import
    @custom_album = CustomAlbum.find(params[:id])
  end

  def importimages
    custom_album = CustomAlbum.find(params[:id])
    workbook = RubyXL::Parser.parse(params["import_file"].tempfile)
    sheet = workbook[0]
    if sheet.count <= 203
      sheet.each_with_index do |row, i|
        next if i < 3
        v = row.cells.first.value rescue nil
        next if v.blank?
        import_this_image(row, custom_album)
      end
      redirect_to admin_custom_gallery_path(custom_album.id)
    else
      redirect_to import_admin_custom_gallery_path(:error => "1")
    end
  end

  def excel_format
    @custom_album = CustomAlbum.find(params[:id])
    respond_to do |format|
      format.xlsx {
        response.headers['Content-Disposition'] = 'attachment; filename="custom_gallery_import_format.xlsx"'
      }
    end
  end

  def set_cover
    if params[:set_cover] == "true"
      custom_album = CustomAlbum.find(params[:custom_album_id])
      image = CustomAlbumImage.find(params[:image_id])
      custom_album.update_attributes({:cover_path => image.file.thumb.url, :cover=>params[:image_id]})
    else
      custom_album = CustomAlbum.find(params[:custom_album_id])
      custom_album.update_attributes({:cover_path => nil, :cover=>"default"})
    end
    render :json =>{"success"=>true}.to_json
  end

  def get_photoData_json
    @custom_album = CustomAlbum.find(params[:id])
    @images = @custom_album.custom_album_images.where(:order => [nil,-1]).desc(:created_at)
    images = @custom_album.custom_album_images.where(:order.gt => -1).asc(:order)
    @images = @images.concat(images)
    image_content = []
    @images.each do |image|
      image_content << {"id" => image.id.to_s,"title"=> image.title_translations, "description" => image.description_translations,"tags" => image.tags.collect{|t| t.id.to_s}}
    end
    render :json=>{"custom_galleries" => image_content}.to_json
  end

  def get_custom_album_json
    custom_albums = CustomAlbum.all
    output = Array.new

    custom_albums.each do |custom_album|
      tag_names = Array.new

      custom_album.tag_ids.each do |tag|
        tag_names << get_tags.include?(tag)
      end
      if custom_album.cover_path
        cover_path = custom_album.cover_path
      else
        cover_path = "/assets/custom_gallery/default.jpg"
      end
      output << {
        custom_album_cover_file: "http://#{request.host_with_port}"+cover_path,
        custom_album_name: custom_album.name,
        custom_album_tag_names: tag_names,
        custom_album_link:"http://#{request.host_with_port}#{panel_custom_gallery_back_end_custom_album_get_imgs_json_path(custom_album)}",
      }
    end

    render :json=>JSON.pretty_generate(output)
  end

  def get_imgs_json
    custom_album = CustomAlbum.find(params[:custom_album_id])
    images = custom_album.custom_album_images.all
    output = Array.new

    images.each do |image|
      tags = Array.new

      image.tag_ids.each do |tag|
        tags << get_tags.include?(tag)
      end
       
      if image.file.theater.present?
        @image_file = image.file.theater.url
      else
        @image_file = image.file.url
      end

      output << {
        image_title: image.title,
        image_description: image.description,
        image_file: { url: "http://#{request.host_with_port}#{@image_file}",
                      thumb: "http://#{request.host_with_port}#{image.file.thumb.to_s}"},
                      image_tag_names: tags}
    end

    render :json=>JSON.pretty_generate(output)
  end

  def imgs
    @custom_album = CustomAlbum.find(params[:custom_gallery_id])
    @tag_names = Array.new
    @images = @custom_album.custom_album_images.asc(:order)
    @output =  Array.new
    @images.each do |values|
    @output << { _id:  values.id.to_s,
                 theater_link: admin_image_path(values),
                 description: values.description,
                 title: values.title,
                 file: values.file.as_json[:file],
                 custom_gallery_custom_album_id: values.custom_album_id,
                 order: values.order,
                 tags: values.tags}
    end
      render :json=>{"images" => @output, "tags" => @custom_album.tags}.to_json
  end


  def upload_process
    if CustomAlbumUnprocess.first.upload_success
      custom_album_unprocess = Array(CustomAlbumUnprocess.all)
      count = custom_album_unprocess.count
      Thread.new do
        custom_album_unprocess.each_with_index do |un_image,i|
          begin
            custom_album = CustomAlbumImage.all.select{|value| value.id.to_s == un_image.image_id.to_s}[0]
            custom_album.file = un_image.save_var
            custom_album.save!
            file = un_image.save_var.tempfile
            file.close
            File.delete file.path
            un_image.delete
            variable = CustomAlbumVariable.first
            variable.progress_filename = custom_album[:file]
            variable.progress_percent = ((i+1)*100.0/count).floor.to_s + '%'
            variable.save!
          rescue => e
            puts ['err',un_image.inspect,e.inspect]
            un_image.destroy
          end
        end
        variable = CustomAlbumVariable.first
        variable.finish = true
        variable.save!
      end
      custom_album_temp = CustomAlbumUnprocess.first
      custom_album_temp.upload_success = false
      custom_album_temp.save!
    end
  end
  def start_upload_process
    custom_album_temp = CustomAlbumUnprocess.first
    custom_album_temp.upload_success = true
    custom_album_temp.save!
    render :json => {}.to_json
  end
  def init_upload
    variable = CustomAlbumVariable.first
    if variable.nil?
      variable = CustomAlbumVariable.new
    end
    variable.count = params['all_length'].to_i
    variable.finish = false
    variable.progress_percent = '0%'
    variable.progress_filename = 'processing!!'
    variable.notalive = true
    variable.save!
    render :json => {}.to_json
  end
  def upload_image
    custom_album = CustomAlbum.find(params[:custom_album_id])
    files = params['files']
    custom_album_unprocess = CustomAlbumUnprocess.new()
    files.each do |file|
        image = custom_album.custom_album_images.new
        image.tags = (custom_album.tags rescue [])
        if(CustomAlbumVariable.first.count==1 rescue true)
          image.file = file
        else
          custom_album_unprocess.image_id = image.id
          custom_album_unprocess.upload_success = false
          custom_album_unprocess.save_var = file
          custom_album_unprocess.save!
          ObjectSpace.undefine_finalizer(file.tempfile)
        end
        image.save!
    end
    render :json=>{"files"=>[{}]}.to_json
  end

  def last_image_id
    custom_album = CustomAlbum.find(params[:custom_albumid])
    lastimage = custom_album.custom_album_images.last
    render :json => {"last_image_id" => lastimage.id.to_s}.to_json
  end

  def new_images 
    @custom_album = CustomAlbum.find(params[:custom_album_id])
    if params[:last_image_id].present?
      lastimage = CustomAlbumImage.find(params[:last_image_id])
      @newimages = @custom_album.custom_album_images.where(:created_at.gt => lastimage.created_at,:order => -1).desc(:created_at)
    else
      @newimages = @custom_album.custom_album_images.where(:order => [nil,-1]).desc(:created_at)
    end
    render :layout=>false
  end


  def images_tags
    custom_album = CustomAlbum.find(params[:custom_album_id])
    tags = Array.new
    images = custom_album.custom_album_images.all
    images.each do |image|
      tags << {"id"=>image.id, "tags" => image.tags}
    end
    render :json=>tags.to_json
  end

  def update
    custom_album = CustomAlbum.find(params[:id])
    tagsToDestroy = []
    tagsToAdd = []
    new_tags = params[:custom_album][:tags] || []
    old_tags = custom_album.tags.collect{|t| t.id.to_s}
    old_tags.each do |tag|
       if !new_tags.include?(tag)
        tagsToDestroy << tag
        end
    end
    if new_tags != nil
      new_tags.each do |tag|
        if !old_tags.include?(tag)
          tagsToAdd << tag
        end
      end
    end
    update_children_image_tag(custom_album,tagsToDestroy,tagsToAdd)
    custom_album.update_attributes(custom_album_params)
    redirect_to "/admin/custom_galleries/"+custom_album.id.to_s
  end

  def update_children_image_tag(custom_album,tagsToDestroy,tagsToAdd)
      # tagsToDestroy will contain  all tag ids which have to be deleted from the galley_images
      # tagsToAdd will contain all tag ids which ve to be added in tall custom_album_images
      images = custom_album.custom_album_images
      images.each do |image|
        image_tags = image.tags.collect{|t| t.id.to_s}
        tagsToAdd.each do |tag|
          image_tags << tag
        end
        tagsToDestroy.each do |tag|
          if image_tags.include?tag
            image_tags.delete(tag)
          end
        end
        image.tags = image_tags
        image.save
      end
  end

  private
    def crop_but_no_backup image
      fname = image.file.path
      extension = File.extname(fname)
      base_name = fname.chomp(extension)
      base_name += ('_resized'+ extension)
      File.file?(base_name)
    end
    def setup_vars
      @module_app = ModuleApp.where(:key=>"custom_gallery").first
    end

    def custom_album_params
      p = params.require(:custom_album).permit!
      p["tags"] = p["tags"] || []
      p
    end
end
