 
 bower                 = require 'bower'
 buster                = require 'gulp-buster'
+childProcess          = require 'child_process'
 clean                 = require 'gulp-clean'
 coffee                = require 'gulp-coffee'
 coffeelint            = require 'gulp-coffeelint'

		.pipe jade options
		.pipe gulp.dest TEMP_DIRECTORY

gulp.task 'less', ['copy:temp'], ->
	options =
		sourceMap: true
		sourceMapBasepath: path.resolve TEMP_DIRECTORY

	gulp
		.src '**/*.less', cwd: TEMP_DIRECTORY
		.pipe less options
		.pipe gulp.dest TEMP_DIRECTORY

gulp.task 'markdown', ['copy:temp'], ->
	gulp
		.src '**/*.{md,markdown}', cwd: TEMP_DIRECTORY
		.pipe markdown()
		.pipe gulp.dest TEMP_DIRECTORY

gulp.task 'ngClassify', ['copy:temp'], ->
	options =
		appName: APP_NAME or 'app'
		data:
			environment: 'dev'

	gulp
		.src '**/*.coffee', cwd: TEMP_DIRECTORY
		.pipe ngClassify options
		.pipe gulp.dest TEMP_DIRECTORY

gulp.task 'open', ['serve'], ->
	options =
		url: "http://localhost:#{DEV_PORT}"

	gulp
		.src 'index.html', cwd: DIST_DIRECTORY
		.pipe open '', options

gulp.task 'reload', ['build'], ->
	gulp
		.src 'index.html', cwd: DIST_DIRECTORY
		.pipe connect.reload()

gulp.task 'scripts', ['coffee']

gulp.task 'serve', ['build'], ->
	connect.server
		livereload: true
		port: DEV_PORT
		root: DIST_DIRECTORY

gulp.task 'spa', ['scripts', 'styles', 'views'], ->
	unixifyPath = (p) ->
			regex = /\\/g
			p.replace regex, '/'

	includify = ->
		scripts = []
		styles = []

		bufferContents = (file) ->
			return if file.isNull()

			ext = path.extname file.path
			p = unixifyPath(path.join('/', path.relative(file.cwd, file.path)))

			return if ext is '.js'
				scripts.push p

			return if ext is '.css'
				styles.push p

		endStream = ->
			payload = {scripts, styles}
			@emit 'data', payload
			@emit 'end', payload

		es.through bufferContents, endStream

	getIncludes = ->
		deferred = q.defer()

		files = []
			.concat SCRIPTS
			.concat STYLES

		gulp
			.src files, cwd: TEMP_DIRECTORY
			.pipe includify()
			.on 'end', (data) ->
				deferred.resolve data

		deferred.promise

	processTemplate = (files) ->
		deferred = q.defer()

		data =
			appName: APP_NAME
			scripts: files.scripts
			styles: files.styles

		gulp
			.src 'index.html', cwd: TEMP_DIRECTORY
			.pipe template data
			.pipe gulp.dest TEMP_DIRECTORY
			.on 'end', ->
				deferred.resolve()

		deferred.promise

	getIncludes()
		.then processTemplate

gulp.task 'styles', ['less']

gulp.task 'test', ['build'], ->
	scripts = SCRIPTS.slice 0

	# remove *.spec exclusion
	scripts.pop()

	options =
		background: true
		basePath: DIST_DIRECTORY
		browsers: [

			'jasmine'
		]
		keepalive: false
		logLevel: 'WARN'
		reporters: [
			'dots'
		]
		singleRun: true
		transports: [
			# 'websocket' # removed due to excessive socket connections
			'flashsocket'
			'xhr-polling'
			'jsonp-polling'
		]

	karma.server.start options

gulp.task 'less', ['copy:temp'], ->
	options =
		sourceMap: true
		sourceMapBasepath: path.resolve TEMP_DIRECTORY

	gulp
		.src '**/*.less', cwd: TEMP_DIRECTORY
		.pipe less options
		.pipe gulp.dest TEMP_DIRECTORY

gulp.task 'markdown', ['copy:temp'], ->
	gulp
		.src '**/*.{md,markdown}', cwd: TEMP_DIRECTORY
		.pipe markdown()
		.pipe gulp.dest TEMP_DIRECTORY

gulp.task 'ngClassify', ['copy:temp'], ->
	options =
		appName: APP_NAME or 'app'
		data:
			environment: 'dev'

	gulp
		.src '**/*.coffee', cwd: TEMP_DIRECTORY
		.pipe ngClassify options
		.pipe gulp.dest TEMP_DIRECTORY

gulp.task 'open', ['serve'], ->
	options =
		url: "http://localhost:#{DEV_PORT}"

	gulp
		.src 'index.html', cwd: DIST_DIRECTORY
		.pipe open '', options

gulp.task 'reload', ['build'], ->
	gulp
		.src 'index.html', cwd: DIST_DIRECTORY
		.pipe connect.reload()

gulp.task 'scripts', ['coffee']

gulp.task 'serve', ['build'], ->
	connect.server
		livereload: true
		port: DEV_PORT
		root: DIST_DIRECTORY

gulp.task 'spa', ['scripts', 'styles', 'views'], ->
	unixifyPath = (p) ->
			regex = /\\/g
			p.replace regex, '/'

	includify = ->
		scripts = []
		styles = []

		bufferContents = (file) ->
			return if file.isNull()

			ext = path.extname file.path
			p = unixifyPath(path.join('/', path.relative(file.cwd, file.path)))

			return if ext is '.js'
				scripts.push p

			return if ext is '.css'
				styles.push p

		endStream = ->
			payload = {scripts, styles}
			@emit 'data', payload
			@emit 'end', payload

		es.through bufferContents, endStream

	getIncludes = ->
		deferred = q.defer()

		files = []
			.concat SCRIPTS
			.concat STYLES

		gulp
			.src files, cwd: TEMP_DIRECTORY
			.pipe includify()
			.on 'end', (data) ->
				deferred.resolve data

		deferred.promise

	processTemplate = (files) ->
		deferred = q.defer()

		data =
			appName: APP_NAME
			scripts: files.scripts
			styles: files.styles

		gulp
			.src 'index.html', cwd: TEMP_DIRECTORY
			.pipe template data
			.pipe gulp.dest TEMP_DIRECTORY
			.on 'end', ->
				deferred.resolve()

		deferred.promise

	getIncludes()
		.then processTemplate

gulp.task 'styles', ['less']

gulp.task 'test', ['build'], ->
	# don't allow karma to block gulp
	spawn = childProcess.spawn 'gulp', ['karma'], {stdio: 'inherit'}

gulp.task 'views', ['jade', 'markdown']

