# encoding: utf-8
require "json"
module ApplicationHelper
	def render_widget(widget)
		file = File.join("../templates", "#{@key}", "modules/#{widget}")
		render :partial => file
	end
	def render_partial(partial)
		file = File.join("../templates", "#{@key}", "partial/#{partial}")
		render :partial => file
	end
	def link_to_show(module_name)
		"/module/#{module_name}/show"
	end
	def render_header
		site = current_site
		header_file = File.join('../templates', "#{@key}", "/home/header.html.erb")
		header_file_html = render :file => header_file
		header = Nokogiri::HTML(header_file_html, nil, "UTF-8")
		sub_menu_html = site.sub_menu
		html = header.to_s
		html = html.gsub("{{site_name}}",(site.title rescue ""))
		html = html.gsub("%7B%7Blogo_url%7D%7D",(site.site_logo.url.nil? ? "/assets/site-logo.png" : site.site_logo.url))
		if site.sitemap_menu_in_header
			sub_menu_html = sub_menu_html + "Sitemap"
		end
		sub_menu_html = sub_menu_html.nil? ? "" : sub_menu_html
		html = html.gsub("{{header-data}}",sub_menu_html)
		html.html_safe
	end
	def render_site_title
		site = current_site
		title = site.title rescue ""
		if site.title_always_on
			if !params[:slug].nil?
				temp_title = params[:slug].sub("-#{params[:uid]}","")
				temp_title = temp_title.gsub("-"," ")
				title = "#{temp_title} | #{title}"
			elsif params[:target_action] == "index"
				temp_title = Page.find_by(:page_id => params[:page_id]).name
				title = "#{temp_title} | #{title}"
			end
		end
		title
	end
	def render_google_analytics
		current_site.google_analytics.html_safe rescue ""
	end
	def render_footer
		site = current_site
		footer_file = File.join('../templates', "#{@key}", "/home/footer.html.erb")
		footer_file_html = render :file => footer_file
		footer = Nokogiri::HTML(footer_file_html, nil, "UTF-8")
		html = footer.to_s
		site_footer = site.footer
		if site.enable_terms_of_use
			site_footer = site_footer + "Terms of use"
		end
		site_footer = site_footer.nil? ? "" : site_footer
		html = html.gsub("{{footer-data}}",site_footer)
		counter = Page.root.view_count.to_s rescue ""
		html = html.gsub("{{site-counter}}",counter)
		html.html_safe
	end
	def render_orbit_bar
		orbit_bar_file = File.join('../views', "orbit_bar", 'index.html.erb')
		orbit_bar_file_html = render :file => orbit_bar_file
		orbit_bar_file_html.html_safe
	end
	def render_menu
		# menu_html = Rails.cache.fetch(['main_menu',request.original_fullpath, I18n.locale], race_condition_ttl: 2.seconds) do
			# json_file = File.read(File.join(Rails.root, 'public', "menu.json"))
			# @items = JSON.parse(json_file)
			if $mobile.blank?
				@pages = Page.root.sorted_published_child_pages
			else
				@pages = Page.root.sorted_published_child_pages_for_mobile
			end
			def create_json(pages)
				item = {}
				pages.each do |page|
					if page.child_page.size > 0
						if page.page_type == "page"
							if $mobile.blank?
								item["#{page.name}"] = {"url"=> "/#{locale.to_s}" + page.url, "children"=>create_json(page.sorted_published_child_pages), "target" => "_self"}
							else
								item["#{page.name}"] = {"url"=> "/#{locale.to_s}" + page.url, "children"=>create_json(page.sorted_published_child_pages_for_mobile), "target" => "_self"}
							end
						elsif page.page_type == "link"
							target = get_target(page.external_url)
							if $mobile.blank?
								item["#{page.name}"] = {"url"=> page.external_url, "children"=>create_json(page.sorted_published_child_pages), "target" => target}
							else
								item["#{page.name}"] = {"url"=> page.external_url, "children"=>create_json(page.sorted_published_child_pages_for_mobile), "target" => target}
							end
						end
					else
						if page.page_type == "page"
							item["#{page.name}"] = {"url"=> "/#{locale.to_s}" + page.url, "target" => "_self"}
						elsif page.page_type == "link"
							item["#{page.name}"] = {"url"=> page.external_url, "target" => get_target(page.external_url)}
						end
					end
				end
				item
			end
			@items = create_json(@pages)
			menu_file = File.open(File.join(Rails.root, 'app', 'templates', "#{@key}", "/home/menu.html.erb"))
			doc = Nokogiri::HTML(menu_file, nil, "UTF-8")
			menu_file.close
			temp = []
			@menus = []
			@menus_items = [] 
			temp << doc.css("*[data-menu-level='0']")
			temp << doc.css("*[data-menu-level='1']")
			temp << doc.css("*[data-menu-level='2']")
			temp[0] = temp[0].to_s.gsub(temp[1].to_s,"{{level}}")
			temp[1] = temp[1].to_s.gsub(temp[2].to_s,"{{level}}")
			temp[2] = temp[2].to_s
			temp.each_with_index do |menu,i|
				t = Nokogiri::HTML(menu, nil, "UTF-8")
				a = t.css("*[data-menu-link='true']")
				a[0]["href"] = "href_here"
				a[0]["target"] = "target_here"
				li = t.css("*[data-menu-level='#{i}'] > *")
				@menus_items << li.to_html
				ul = t.css("*[data-menu-level='#{i}']")
				ul[0].inner_html = "{{here}}"
				@menus << ul[0].to_html
			end
			def create_menu(items,level)
				html = ""
				items.each do |key,item|
					li = @menus_items[level].gsub("href_here",(item["url"] || ""))
					li = li.gsub("{{link_name}}",(key || ""))
					li = li.gsub("target_here",(item["target"] || ""))
					li = request.original_fullpath == item['url'] ? li.gsub("{{active}}","active") : li.gsub("{{active}}","")
					if item["children"] && !item["children"].empty?
						li = li.gsub("{{level}}",create_menu(item["children"],level + 1))
					else
						li = li.gsub("{{level}}","")
					end
					html = html + li
				end
				html = @menus[level].gsub("{{here}}",html)
				html = html.gsub("{{class_level}}",level.to_s)
				html
			end
			h = create_menu(@items,0)
			h.html_safe
		# end
		# menu_html
	end
	def render_view
		def render_link_to_edit(html, url_to_edit)
			if html.scan("{{link_to_edit}}").length == 0
				html = url_to_edit.blank? ? html : html + "
 #{t(:edit)}
"
			else
				html = url_to_edit.blank? ? html.gsub("{{link_to_edit}}","") : html.gsub("{{link_to_edit}}"," #{t(:edit)}
")
			end
			return html
		end
		def parsing_repeats_again(elements,d,level)
			newhtml = []
			oldhtml = []
			elements.each do |el|
				html_to_render = ""
				data_name = el.attr("data-list")
				wrap_elements = el.css("*[data-list][data-level='#{level}']")
				if d[data_name]
					d[data_name].each_with_index do |item,i|
						element = el.inner_html
						if wrap_elements.count > 0
							htmls = parsing_repeats_again(wrap_elements,d[data_name][i], level + 1)
							htmls[0].each_with_index do |html,i|
								element = element.gsub(html,htmls[1][i])      
							end
						end
						item.each do |key,value|
							if !value.kind_of?(Array)
								value = value.nil? ? "" : value
								element = element.gsub("{{#{key}}}",value.to_s.html_safe)
								element = element.gsub("%7B%7B#{key}%7D%7D",value.to_s.html_safe)
								element = render_link_to_edit(element, value) if key.eql?("url_to_edit")
							end
						end
						html_to_render = html_to_render + element
					end
					temp = el.to_s
					oldhtml << temp
					temp = temp.gsub(el.inner_html, html_to_render)
					newhtml << temp
				end
			end
			[oldhtml,newhtml]
		end
		if params[:target_action] == "index"
			f = File.join(Rails.root, 'app', 'templates', "#{@key}", 'modules', params[:target_controller].singularize, "#{params[:layout_type]}.html.erb")
			if !File.exists?f
				f = File.join(Rails.root, 'app', 'templates', "#{@key}", 'modules', params[:target_controller].singularize, "index.html.erb")
				if !File.exists?f
					return "Maybe the administrator has changed the theme, please select the index page design again from the page settings.
".html_safe
				end
			end
			file =  File.open(f)
			doc = Nokogiri::HTML(file, nil, "UTF-8")
			file.close
			controller = "#{params[:target_controller].capitalize}_controller".classify.constantize.new
			begin 
				data = controller.send("#{params[:target_action]}")# rescue nil
			rescue Exception => e  
			 write_debug_file(e,params[:target_controller],params[:target_action]) if Site::DEBUG
			end 
			if !data.nil?
				wrap_elements = doc.css("*[data-list][data-level='0']")
				htmls = parsing_repeats_again(wrap_elements,data,1)
				html = doc.to_s
				htmls[0].each_with_index do |h,i|
					html = html.gsub(h,htmls[1][i])
				end
				extras = data["extras"] || {}
				extras["page-title"] = Page.find_by(:page_id => params[:page_id]).name rescue "" if !extras["page-title"]
				extras.each do |key,value|
					value = value.nil? ? "" : value
					html = html.gsub("{{#{key}}}",value.to_s.html_safe)
					html = html.gsub("%7B%7B#{key}%7D%7D",value.to_s.html_safe)
				end
				total_pages = data['total_pages'].to_i rescue 1
				if total_pages > 1
					html = html.gsub("{{pagination_goes_here}}",create_pagination(total_pages))
				else
					html = html.gsub("{{pagination_goes_here}}","");
				end
				html.html_safe
			else
				return "No content to show.
".html_safe
			end
		else
			f = File.join(Rails.root, 'app', 'templates', "#{@key}", 'modules', params[:target_controller].singularize, "#{params[:target_action]}.html.erb")
			if File.exists?f
				file =  File.open(f)
				doc = Nokogiri::HTML(file, nil, "UTF-8")
				file.close
				controller = "#{params[:target_controller].capitalize}_controller".classify.constantize.new
				begin 
					data = controller.send("#{params[:target_action]}")# rescue nil
				rescue Exception => e  
			 		write_debug_file(e,params[:target_controller],params[:target_action]) if Site::DEBUG
				end 
				if data.nil?
					return " No content to show. 
".html_safe
				end
				if data.blank? || data.empty?
					file =  File.open("#{Rails.root}/public/404.html")
					doc = Nokogiri::HTML(file, nil, "UTF-8")
					file.close
					doc.to_html.html_safe
				else
					unless data['impressionist'].blank?
						Thread.new do
							impression = data['impressionist'].impressions.create
							impression.user_id = request.session['user_id']
							impression.controller_name = params[:target_controller]
							impression.action_name = params[:target_action]
							impression.ip_address = request.remote_ip
							impression.session_hash = request.session.id
							impression.request_hash = @impressionist_hash
							impression.referrer = request.referrer
							impression.save
							data['impressionist'].inc(view_count: 1)
						end
					end
					wrap_elements = doc.css("*[data-list][data-level='0']")
					if wrap_elements.count == 0
						wrap_element_html = doc.to_s
						el = wrap_element_html
						data.each do |key,value|
				  			next if key.eql? 'impressionist'
							value = value.nil? ? "" : value
							el = el.gsub("{{#{key}}}",value.to_s.html_safe)
							el = el.gsub("%7B%7B#{key}%7D%7D",value.to_s.html_safe)
						end
						el.html_safe
					else
						keys = data.keys
						not_array_key = nil
						data.keys.each do |key|
							not_array_key = key if data["#{key}"].kind_of?(Hash)
						end
						htmls = parsing_repeats_again(wrap_elements,data,1)
						html = doc.to_s
						htmls[0].each_with_index do |h,i|
							html = html.gsub(h,htmls[1][i])
						end
						extras = data["#{not_array_key}"] || {}
						extras.each do |key,value|
							next if key.eql? 'impressionist'
							value = value.nil? ? "" : value
							html = html.gsub("{{#{key}}}",value.to_s)
							html = html.gsub("%7B%7B#{key}%7D%7D",value.to_s)
						end
						html = render_link_to_edit(html, data["url_to_edit"]) if !data["url_to_edit"].nil?
						html.html_safe
					end
				end
			else
				return "There is a problem with the design. We will try to fix it as soon as possible. Sorry for the inconvenience!! :(
".html_safe
			end
		end
	end
	def action_data
		controller = "#{params[:target_controller].capitalize}_controller".classify.constantize.new
		data = controller.send("#{params[:target_action]}")
		data
	end
	def active_for_controllers(*controller_names)
    	(controller_names.include?(controller.controller_name) || controller_names.include?(request.fullpath)) ? 'active' : nil
  	end
  	def visible_for_controllers(*controller_names)
    	(controller_names.include?(controller.controller_name) || controller_names.include?(request.fullpath)) ? '' : 'hide'
  	end
	def active_for_action(controller_name, action_name)
    	((controller.controller_name.eql?(controller_name) || request.fullpath.eql?(controller_name)) && controller.action_name.eql?(action_name)) ? 'active' : nil
  	end
  	def link_back(custom_class=nil, params="")
    	case custom_class
    	when nil
     		link_to t('back'), get_go_back + params, :class => 'nav'
    	else
      		link_to t('back'), get_go_back + params, :class => custom_class
    	end
  	end
  	def switch_language(loc)
  		url = request.original_fullpath
  		
  		locale = url.include?("zh_cn") ? :zh_cn : I18n.locale
  		url = url.gsub("/#{locale.to_s}/","/#{loc.to_s}/")
  		url = url.gsub("locale=#{locale.to_s}","locale=#{loc.to_s}") if url == request.original_fullpath
  		url = url + "#{url.include?("?") ? "&" : "?"}locale=#{loc.to_s}" if url == request.original_fullpath and (!url.include?('/'+locale.to_s) or !url.include?(locale.to_s+'='))
  		url
  	end
  	# Clean the link back
  	def get_go_back
    	begin
      		if request.url.include?('locale=')
        	session[:last_page]
      	else
        	session[:last_page] = remove_locale(request.referer)
      	end
    	rescue
      		eval(params[:controller].split('/').join('_') << '_url')
    	end
  	end
  	def show_avatar(user)
    	image_tag(user.avatar.thumb.url)
  	end
  	def render_sitemap
  		items = action_data
  		def node(items, level)
  			class_name = nil
  			case level
  			when 0 
                class_name = "sitemap-list level-1"
            when 1
                class_name = "sitemap-list level-2"
            when 2
                class_name = "sitemap-list level-3"
  			end
  			html = ""
  			items.each do |key,item|
  				if item["children"] && !item["children"].empty?
  					url = item["url"]
  					target = item["target"]
  					html = html + "- #{key}"
  					html = html + node(item["children"],level + 1)
  					html = html + "
 "
  				else
  					target = item["target"]
  					url = item["url"]
  					html = html + "- #{key}
 "
  				end
  			end
  			html = html + "
"
  			html
  		end
  		html = node(items,0)
  		html.html_safe
  	end
  	def show_attribute_value(value)
    	if value.kind_of? Hash
        	result = []
        	value.each{|t| result.push(t.last)}
        	result.join ","
      	else
        	value
    	end
  	end
  	def create_pagination(total_pages)
  		file = File.join(Rails.root, 'app', 'templates', "#{@key}", 'home', "pagination.html.erb")
  		html = ""
  		if File.exists?file
			file =  File.open(file)
			doc = Nokogiri::HTML(file, nil, "UTF-8")
			file.close
			querystring = request.GET rescue {}
			querystring.delete("page_no")
			paginationobj = doc.css("*[data-pagination='true']").first
			in_html = first = last = nextpage = prevpage = paginationobj.inner_html
			f_html = ""
			current_page_number = OrbitHelper.page_number
			if current_page_number > 1
				first = first.gsub("%7B%7Bpagination_link%7D%7D","?page_no=1{querystring.to_query}")
				first = first.gsub("{{page_number}}","First")
				first = first.gsub("{{pagination_active}}","")
				f_html = f_html +  first
			end
			start_number = current_page_number - 2 
			end_number = current_page_number + 2
			if end_number > total_pages
				end_number = total_pages
				start_number = total_pages - 4
			end
			if start_number < 1
				start_number = 1
				end_number = 5
			end
			end_number = end_number > total_pages ? total_pages : end_number
			(start_number..end_number).each do |i|
				h = in_html
				h = h.gsub("%7B%7Bpagination_link%7D%7D","?page_no=#{i.to_s}{querystring.to_query}")
				h = h.gsub("{{page_number}}",i.to_s)
				h = h.gsub("{{pagination_active}}",(i == current_page_number ? "active" : ""))
				f_html = f_html + h
			end
			if current_page_number > 1
				prevpage = prevpage.gsub("%7B%7Bpagination_link%7D%7D","?page_no=#{current_page_number - 1}{querystring.to_query}")
				prevpage = prevpage.gsub("{{page_number}}","«")
				prevpage = prevpage.gsub("{{pagination_active}}","")
				f_html = f_html +  prevpage
			end
			if current_page_number < total_pages
				nextpage = nextpage.gsub("%7B%7Bpagination_link%7D%7D","?page_no=#{current_page_number + 1}{querystring.to_query}")
				nextpage = nextpage.gsub("{{page_number}}","»")
				nextpage = nextpage.gsub("{{pagination_active}}","")
				f_html = f_html +  nextpage
				last = last.gsub("%7B%7Bpagination_link%7D%7D","?page_no=#{total_pages}{querystring.to_query}")
				last = last.gsub("{{page_number}}","Last")
				last = last.gsub("{{pagination_active}}","")
				f_html = f_html +  last
			end
			paginationobj.inner_html = f_html
			html = paginationobj.to_s
		end
		html
  	end
  	def get_target(link)
  		target = "_blank"
  		if !link.nil?
	  		link = link.split("?").first
			temp_url = URI.parse(link)
			if temp_url.host.nil?
				target = "_self"
			end
		end
		target
  	end
  	def write_debug_file(e,controller_name,action_name)
   		url_dir_name = request.fullpath.split("?")[0]
   		url_dir_name = URI.decode(url_dir_name)
      	url_dir_name = (url_dir_name  == "/" ? "home" : url_dir_name.sub("/","").gsub("/","_").gsub("-","_").gsub(" ","_"))
      	directory_name = "tmp/debug/#{url_dir_name}"
      	FileUtils.mkdir_p(directory_name) unless File.exists?(directory_name)
  		fn = "#{directory_name}/#{controller_name}_#{action_name}.html"
  		error_trace_spans = ""
  		e.backtrace.each do |bt|
  			error_trace_spans = error_trace_spans + "#{bt}
"
  		end
  		con = "#{controller_name.capitalize}_controller".classify.constantize
  		File.open(fn, "w"){ |file| 
  			file.puts "
  						
  						    
                			
  							Debug result
  						
  						
  							Error Message
  							
  								
#{e.message}
  							
  							Request Details
  							
  								Url : #{URI.decode(request.url)}
  								Controller : #{con.to_s} 
  								Action : #{action_name.capitalize} 
  							
  							Error Trace
  							
  								#{error_trace_spans}
  							
  							Params
  							
  								#{OrbitHelper.params}
  							
  						
  						"
  		}
  	end
end