 module.exports = (grunt) ->
 
   grunt.initConfig
+
     bower:
       install:
         options:
-          layout: 'byComponent'
+          layout: 'byType'
           targetDir: 'public/lib/'
+
+    clean:
+      main:
+        files: [
+          src: 'public/**/*'
+        ]
+
+    coffee:
+      compile:
+        files: [
+          dest: 'public/js/'
+          expand: true
+          ext: '.js'
+          rename: (dest, matchSrcPath, options) ->
+            require('path').join dest, matchSrcPath.replace 'public/coffee/', ''
+          src: 'public/coffee/**/*.coffee'
+        ]
+      options:
+        bare: true
+        sourceMap: true
+
     connect:
       server:
         options:
           base: 'public/'
           livereload: 35729
-          port: 3000
+
     copy:
-      main:
+      coffee:
         files: [
-          dest: 'public/js/'
+          dest: 'public/'
           expand: true
-          filter: 'isFile'
-          flatten: true
-          src: 'js/*'
+          src: 'coffee/**/*.coffee'
         ]
+      js:
+        files: [
+          dest: 'public/'
+          expand: true
+          src: 'js/**/*.js'
+        ]
+
     jade:
       compile:
         files: [
           dest: 'public/'
           expand: true
           ext: '.html'
-          flatten: true
+          rename: (dest, matchSrcPath, options) ->
+            require('path').join dest, matchSrcPath.replace 'jade/', ''
           src: 'jade/!(_)*.jade'
         ]
       options:
         pretty: true
+
+    less:
+      compile:
+        files: [
+          dest: 'public/css/'
+          expand: true
+          ext: '.css'
+          rename: (dest, matchSrcPath, options) ->
+            require('path').join dest, matchSrcPath.replace 'less/', ''
+          src: 'less/**/!(_)*.less'
+        ]
+
     stylus:
       compile:
         files: [
           dest: 'public/css/'
           expand: true
           ext: '.css'
-          flatten: true
+          rename: (dest, matchSrcPath, options) ->
+            require('path').join dest, matchSrcPath.replace 'stylus/', ''
           src: 'stylus/!(_)*.{styl,stylus}'
         ]
       options:
         compress: false
-    less:
-      compile:
-        files: [
-          dest: 'public/css/'
-          expand: true
-          ext: '.css'
-          flatten: true
-          src: 'less/!(_)*.less'
-        ]
-    coffee:
-      compile:
-        files: [
-          dest: 'public/js/'
-          expand: true
-          ext: '.js'
-          flatten: true
-          src: 'coffee/*.coffee'
-        ]
-      options:
-        bare: true
-        sourceMap: true
+
     esteWatch:
-      options:
-        dirs: ['js/**', 'jade/**', 'stylus/**', 'less/**', 'coffee/**']
-        livereload:
-          enabled: true
-          extensions: ['js', 'jade', 'styl', 'stylus', 'less', 'coffee']
-          port: 35729
-      js: (filepath) ->
-        conf = grunt.config('copy.main.files')[0]
+      coffee: (filepath) ->
+        # copy to public dir
+        conf = grunt.config('copy.coffee.files')[0]
         conf.src = filepath
-        grunt.config 'copy.main.files', [conf]
-        'copy'
+        grunt.config 'copy.coffee.files', [conf]
+        # compile copied file
+        conf = grunt.config('coffee.compile.files')[0]
+        conf.src = filepath.replace 'coffee/', 'public/coffee/'
+        grunt.config 'coffee.compile.files', [conf]
+        ['copy:coffee', 'coffee']
       jade: (filepath) ->
         return if /_[^\/]*\.jade$/.test filepath
         conf = grunt.config('jade.compile.files')[0]
         conf.src = filepath
         grunt.config 'jade.compile.files', [conf]
         'jade'
+      js: (filepath) ->
+        conf = grunt.config('copy.js.files')[0]
+        conf.src = filepath
+        grunt.config 'copy.js.files', [conf]
+        'copy:js'
+      less: (filepath) ->
+        return if /_[^\/]*\.less$/.test filepath
+        conf = grunt.config('less.compile.files')[0]
+        conf.src = filepath
+        grunt.config 'less.compile.files', [conf]
+        'less'
+      options:
+        dirs: ['coffee/**', 'jade/**', 'js/**', 'less/**', 'stylus/**']
+        livereload:
+          enabled: true
+          extensions: ['coffee', 'jade', 'js', 'less', 'styl', 'stylus']
+          port: 35729
       styl: '<%= esteWatch.stylus %>'
       stylus: (filepath) ->
         return if /_[^\/]*\.styl(?:us)?$/.test filepath

  grunt.loadNpmTasks 'grunt-contrib-stylus'
  grunt.loadNpmTasks 'grunt-este-watch'

  grunt.registerTask 'default', ['connect', 'jade', 'stylus', 'less', 'coffee', 'copy', 'esteWatch']
  grunt.registerTask 'install', ['bower:install']

  return

        conf.src = filepath
        grunt.config 'stylus.compile.files', [conf]
        'stylus'

  grunt.loadNpmTasks 'grunt-bower-task'
  grunt.loadNpmTasks 'grunt-contrib-clean'
  grunt.loadNpmTasks 'grunt-contrib-coffee'
  grunt.loadNpmTasks 'grunt-contrib-connect'
  grunt.loadNpmTasks 'grunt-contrib-copy'
