=begin
  Copyright (c) 2009 Infosoft Global Private Limited 
  FCExporter is a Controller that handles 
  FusionCharts (since v3.1) Server Side Export feature.
  This in conjuncture with other FusionCharts controllers and libraries would 
  process FusionCharts Export Data POSTED to it from FusionCharts 
  and convert the data to image or PDF and subsequently save to the 
  server or response back as http response to client side as download.
 
  This script might be called as the FusionCharts Exporter - main module 
 
     @author InfoSoft Global (P) Ltd.
     @description FusionCharts Exporter (Server-Side - RoR)
     @version 2.0 [ 19 February 2009 ]
   
 
   ChangeLog / Version History:
   ----------------------------
 
    2.0 [ 19 February 2009 ] 
        - Integrated TIMESTAMP?RANDOM filename suffix and used HTTP_URI
    1.0 [ 16 February 2009 ] 
        - Integrated with new Export feature of FusionCharts 3.1
        - can save to server side directory
        - can provide download or open in browser window/frame other than _self
        - can report back to chart
        - can save as PDF/JPG/PNG/GIF
 
  GENERAL NOTES
  -------------

  Chart would POST export data (which consists of encoded image data stream,  
  width, height, background color and various other export parameters like 
  exportFormat, exportFileName, exportAction, exportTargetWindow) to this script. 
 
  The script would process this data and render_component appropriate resource files  which build 
  export binary (PDF/image) 
 
   The component either saves the binary as file to a server side directory or push it as
   Download or open in a new browser window/frame.
 
 
   ISSUES
   ------
    Q> What if someone wishes to open in the same page where the chart existed as postback
       replacing the old page?
  
    A> Not directly supported using any chart attribute or parameter but can do by
       removing/commenting the line containing 'header( content-disposition ...' in the specific controllers
      
=end
class Fusioncharts::FcExporterController < ApplicationController
    require 'fusioncharts/exporter/error_handler'
    require 'fusioncharts/exporter/save_helper'
    require 'fusioncharts/exporter/properties'
    @@default_parameter_values = {"exportfilename"=>"FusionCharts", "exportaction"=>"download", "exporttargetwindow"=>"_self", "exportformat"=>"PDF"}
    
    @@error_codes=""
    def index

      # THis is not being used
      #~ if(FileTest.exists?(Fusioncharts::Exporter::Properties.RESOURCEPATH + "validation_def.rb"))
        #~ require ''+Fusioncharts::Exporter::Properties.RESOURCEPATH + "validation_def"
      #~ end
      
      #parse export stream
      @@export_data = parse_export_request_stream(params)
      target=@@export_data['parameters']['exporttargetwindow']
      exportaction = @@export_data['parameters']['exportaction']
      is_html = exportaction.eql?("download")
      
      
      
      validate_parameters(params)
      
      # Check if resource is present, otherwise quit
      path = get_exporter(@@export_data['parameters']['exportformat'].upcase)
      
      resource_err_codes = validate_resources(path)
      if(resource_err_codes!=nil and !resource_err_codes.empty?)
          # check if there is an error, append the errors/notices
          @@error_codes+=resource_err_codes
          
        end
        if(resource_err_codes.index("E")!=nil)
          logger.info "Showing Errors!!!!\n"
          Fusioncharts::Exporter::ErrorHandler.set_flash_err(@@error_codes,flash,is_html,@@export_data['meta'])
          # Error has occurred, quit further processing
          redirect_to :action=>'error',:target=>target
         return
       end
      
      

      logger.info "Export Action="+ @@export_data['parameters']['exportaction']
      
      if(!exportaction.eql?("download"))
        # Save action
      server_save_error_codes=  validate_for_save(@@export_data['parameters']['exportfilename'],@@export_data['parameters']['exportformat'].downcase)
       if(server_save_error_codes!=nil and !server_save_error_codes.empty?)
          # check if there is an error, append the errors/notices
          @@error_codes+=server_save_error_codes
        end
        if(server_save_error_codes.index("E")!=nil)
          logger.info "Showing Errors!!!!\n"
           Fusioncharts::Exporter::ErrorHandler.set_flash_err(@@error_codes,flash,is_html,@@export_data['meta'])
          # Error has occurred, quit further processing
          redirect_to :action=>'error',:target=>target
         return
       end
      end
      
     #WORKS!
     render_component(:controller=>path , :action=>"export_processor", :params=>{:export_data=>@@export_data})
    end
    
  # This action will render the errors, shows the error.html.erb which contains flash[:notice] and flash[:error]
  # To build the error message as response, build_error_response method from Fusioncharts::Exporter::ErrorHandler is used
  def error
       target = params[:target]

       headers["Content-type"]="text/html"
       if(target.downcase == "_self") 
            headers["Content-Disposition"]='attachment'
      else 
            headers["Content-Disposition"]='inline'
      end
        
         logger.info("Rendering Error Page")
    end
        
    def parse_export_request_stream(export_request_stream)
      #String of compressed data
      #Get all export parameters
      #get width and height of the chart
      #Background color of chart
      meta_hash = {"width"=>export_request_stream[:meta_width],
      "height"=>export_request_stream[:meta_height],
      "bgColor"=>export_request_stream[:meta_bgColor],
      "DOMId"=>export_request_stream[:meta_DOMId]}
      
      export_data = {"stream"=>export_request_stream[:stream],
      "parameters"=>parse_params(export_request_stream[:parameters]),
      "meta"=>meta_hash}

      export_data['parameters'] = parse_params(export_request_stream[:parameters])

      return export_data
    end
    def get_exporter(str_format)
      #path = RESOURCEPATH + EXPORTHANDLER
      
      if(Fusioncharts::Exporter::Properties.HANDLERASSOCIATIONSHASH[str_format] != nil)
        exporter_suffix = Fusioncharts::Exporter::Properties.HANDLERASSOCIATIONSHASH[str_format]
      else
        exporter_suffix = str_format
      end
      path = Fusioncharts::Exporter::Properties.RESOURCEPATH + Fusioncharts::Exporter::Properties.EXPORTHANDLER + exporter_suffix.downcase 
      logger.info "THE PATH TO BE RENDERED IS " + path
        return path
      #end  
    end
    def parse_params(str_params)
      params_values = bang str_params
      @@default_parameter_values.each do |match,value| 
        if(params_values[match.to_i] == nil)
          params_values[match.to_i] = value
        end
      end  
      return params_values
    end

    def output_export_object(export_obj,export_params)
      #filename = export_params[:exportfilename]
      #ext = '.' + export_params[:exportformat]
      #target = export_params[:exporttargetaction]
      action = export_params[:exportaction]
      return export_output(export_obj, export_params[:exportfilename], export_params[:exportformat].downcase, 1, action.downcase=="download", export_params[:exporttargetwindow])
    end
    
    def bang(array)
      delimiter_list = ["|","="]
      ret_array = {}
      tmp_array = array.split(delimiter_list[0])
      0.upto(tmp_array.length-1) do |i|
        tmp2_array = tmp_array[i].split(delimiter_list[1])
        if(tmp2_array.length > 1)
          ret_array =ret_array.merge!(tmp2_array[0].downcase=>tmp2_array[1])
        end
      end
      return ret_array
    end
    
    # Method to redirect using POST method instead of GET
    #For Future use:  need to complete this method and try it , instead of render_component
    def redirect_post(controller_path,action_name,redirect_post_params)
    
    end    
private  
# Check if width, height and stream parameters are in order
  def validate_parameters(params)
      exportaction = params['parameters']['exportaction'].nil? ? params['parameters']['exportaction'] : @@default_parameter_values['exportaction']
      
      is_html = exportaction.eql?("download")
      target = params['parameters']['exporttargetwindow'].nil? ? params['parameters']['exporttargetwindow'] : @@default_parameter_values['exporttargetwindow']
      if(params[:meta_width].nil?)
        err_codes = "W513"
        @@error_codes+=err_codes
       
      end
      if(params[:meta_width].nil? or  params[:meta_height].nil? or params[:meta_width]==0 or params[:meta_height]==0)
        err_codes = "E100"
        @@error_codes+=err_codes
        set_flash_err(@@error_codes,flash,is_html)
        redirect_to :action=>'error',:target=>target
      end
      if(params[:stream].nil? )
        @@error_codes+=err_codes
        set_flash_err(@@error_codes,flash,is_html)
        redirect_to :action=>'error',:target=>target
      end
  end
    # Check if Resource Controllers are present
    def validate_resources(rel_resource_path)
      err_codes=""
      abs_path = File.expand_path("./app/controllers")+rel_resource_path+"_controller.rb"
      logger.info "ABS PATH TO RESOURCE"+abs_path
      if(!FileTest.exists?(abs_path))
        err_codes="E404"
      end
      return err_codes
    end
    
    # Check if server is ready for save action
     def validate_for_save(filename,extension)
        #TODO Check if SAVEPATH ends with / otherwise append /
        abs_path = File.expand_path(Fusioncharts::Exporter::Properties.SAVEPATH)
       server_save_error_codes= Fusioncharts::Exporter::SaveHelper.check_server_save_status(abs_path,filename+"."+extension,Fusioncharts::Exporter::Properties.OVERWRITEFILE,Fusioncharts::Exporter::Properties.INTELLIGENTFILENAMING)
       return server_save_error_codes
     end

end
