
#	This file is part of the "jQuery.Syntax" project, and is distributed under the MIT License.
#	See <jquery.syntax.js> for licensing details.
#	Copyright (c) 2011 Samuel G. D. Williams. <http://www.oriontransfer.co.nz>

require 'stringio'
require 'fileutils'
require 'tmpdir'
require 'pathname'
require 'yaml'

require 'closure-compiler'

require_relative 'ext/theme'

CACHE_FILE = "jquery.syntax.cache.js"
MINIFIED_FILE = "jquery.syntax.min.js"

LICENSE = <<EOF
// This file is part of the "jQuery.Syntax" project, and is distributed under the MIT License.
EOF

BASE_PATH = Pathname(Dir.getwd)
DIST_PATH = 'dist'

def initialize(*)
	super
	@config = nil
end

# if ENV['PREFIX']
# 	Dir.chdir(ENV['PREFIX'])
# end

def update_aliases
	code = StringIO.new
	
	code.puts "// This file is automatically generated. Any changes may be lost."
	code.puts "// The following declarations describes all resources that might be loaded dynamically."
	code.puts
	
	code.puts "// Brush Aliases"
	
	Dir["jquery.syntax.brush.*.js"].sort.each do |path|
		File.open(path, "r") do |f|
			first_line = f.readline rescue ""
			
			if first_line.match(/^\/\/ brush: (.+?) aliases: (.+)$/)
				code.puts "Syntax.alias(#{$1}, #{$2});"
			end
		end
	end
	
	styles = {}
	Dir["**/jquery.syntax.*.css"].sort.each do |path|
		basename = File.basename(path, ".css")
		styles[basename] ||= []
		styles[basename] << path
	end
	
	code.puts
	code.puts "// CSS Extensions"
	styles.each do |basename, paths|
		code.puts "Syntax.styles[#{basename.inspect}] = #{paths.inspect};"
	end
	
	code.puts
	code.puts "// Theme Configuration"
	Dir["**/theme.js"].sort.each do |path|
		code.write File.read(path)
	end
	
	File.open(CACHE_FILE, "w") do |f|
		f.write(code.string)
	end
	
	puts "*** Written updated cache file #{CACHE_FILE} ***"
	# puts code.string
end

def generate_stylesheets(theme: "base")
	output = File.expand_path(theme)
	FileUtils.mkdir_p(output)
	
	cache_path = File.expand_path(".sass-cache", __dir__)
	
	aggregate_theme = Theme.new(output, File.join(File.dirname(__FILE__), "themes"))
	aggregate_theme.load_theme(theme)
	
	Dir.glob(File.join(output, "jquery.syntax.*.{sass,scss}")) do |sass|
		output_name = File.basename(sass).sub(/\.(sass|scss)$/, ".css")
		output_path = File.join(output, output_name)
		
		command = ["sass", "--sourcemap=none", "-I", output, "--stdin", output_path, "--cache-location", cache_path]
		
		IO.popen(command, "w") do |io|
			aggregate_theme.includes_for(sass, :prepend).each do |incl|
				io.puts("@import #{incl}")
			end
			
			io.puts("@import #{File.basename(sass)}")
			
			aggregate_theme.includes_for(sass, :append).each do |incl|
				io.puts("@import #{incl}")
			end
			
			io.close_write
		end
	end
	
	Dir.glob(File.join(output, "*.{sass,scss}")) do |path|
		FileUtils.rm path
	end
	
	Dir.glob(File.join(output, "_*")) do |path|
		FileUtils.rm path
	end
end

# This builds a combined jquery.syntax.js and jquery.syntax.cache.js and minifies the result
def build_combined
	self.update_aliases
	
	compiler = Closure::Compiler.new
	
	output = compiler.compile_files(
		["jquery.syntax.js", "jquery.syntax.cache.js"]
	)
	
	File.open(MINIFIED_FILE, "w") do |file|
		file.write(LICENSE)
		file.write(output)
	end
end

# Note... this is one way !
def compress_all
	self.build_combined
	
	files = Dir["jquery.syntax*.js"]
	compiler = Closure::Compiler.new
	
	puts "Minifying JavaScript..."
	files.each do |path|
		puts "Minifying #{File.basename(path)}..."
		
		output = compiler.compile_files([path])
		
		File.open(path, "w") do |file|
			file.write(LICENSE)
			file.write(output)
		end
	end
end

def setup_prefix
	if ENV['CONFIG']
		config_path = BASE_PATH + ENV['CONFIG']
	else
		config_path = BASE_PATH + "site.yaml"
		unless File.exist? config_path
			config_path = BASE_PATH + "install.yaml"
		end
	end

	puts "Using configuration #{config_path}"	
	@config = YAML::load_file(config_path)
	
	if @config['prefix'] && !ENV['PREFIX']
		prefix = config_path.dirname + (@config['prefix'] || DIST_PATH)
	elsif ENV['PREFIX']
		prefix = BASE_PATH + ENV['PREFIX']
	else
		prefix = BASE_PATH + DIST_PATH
	end
	
	prefix.mkpath
	Dir.chdir(prefix)
	
	ENV['PREFIX'] = prefix.to_s
	
	puts "Working in #{Dir.getwd}..."
end

def install
	self.setup_prefix
	self.clean
	
	@config['themes'].each do |theme|
		self.generate_stylesheets(theme: theme)
	end
	
	js_files = Dir[BASE_PATH + "source/jquery.syntax*.js"]
	
	js_files.each do |path|
		$stderr.puts "Copying #{File.basename(path)}..."
		
		output_path = File.basename(path)
		
		FileUtils.cp(path, output_path)
	end
	
	self.build_combined
	self.compress_all if @config['minify']
	
	puts "Install into #{Dir.getwd} finished."
end

def clean
	self.setup_prefix
	
	Dir.glob("*") do |path|
		FileUtils.rm_r path
	end
end

def default
	self.install
end