text: 'use strict';
  
  module.exports = function (grunt) {
  
    // Time how long tasks take. Can help when optimizing build times
    require('time-grunt')(grunt);
  
    // Automatically load required Grunt tasks
    require('jit-grunt')(grunt, {
      useminPrepare: 'grunt-usemin',
      ngtemplates: 'grunt-angular-templates',
      cdnify: 'grunt-google-cdn'
    });
  
    // Configurable paths for the application
    var appConfig = {
      app: 'inno',
      dist: 'dist'
    };
  
    // Define the configuration for all the tasks
    grunt.initConfig({
  
      // Project settings
      innoplexus: appConfig,
  
      // Watches files for changes and runs tasks based on the changed files
      watch: {
        // bower: {
        //   files: ['bower.json'],
        //   tasks: ['wiredep']
        // },
        js: {
          files: ['<%= innoplexus.app %>/**/*.js'],
          tasks: ['newer:jshint:all', 'newer:jscs:all'],
          options: {
            livereload: '<%= connect.options.livereload %>'
          }
        },
        jsTest: {
          files: ['test/spec/**/*.js'],
          tasks: ['newer:jshint:test', 'newer:jscs:test', 'karma']
        },
        // compass: {
        //   files: ['<%= innoplexus.app %>/styles/{,*/}*.{scss,sass}'],
        //   tasks: ['compass:server', 'postcss:server']
        // },
        // css: {
        //   files: ['app/styles/**/*.{scss,sass}',],
        //   tasks: ['sass']
        // },
        includeSource: {
          files: ['<%= innoplexus.app %>/index.html'],
          tasks: ['includeSource:server']
        },
        sass: {
            files: ['<%= innoplexus.app %>/assets/styles/{,*/}*.{scss,sass}'],
            tasks: ['sass:server']
        },
        jade: {
          files: ['<%= innoplexus.app %>/{,*/}*.jade'],
          tasks: ['jade']
        },
        gruntfile: {
          files: ['Gruntfile.js']
        },
        livereload: {
          options: {
            livereload: '<%= connect.options.livereload %>'
          },
          files: [
            '<%= innoplexus.app %>/{,*/}*.html',
            '.tmp/styles/{,*/}*.css',
            '<%= innoplexus.app %>/assets/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
          ]
        }
      },
  
      // The actual grunt server settings
      connect: {
        options: {
          port: 9000,
          // Change this to '0.0.0.0' to access the server from outside.
          hostname: 'localhost',
          livereload: 35729
        },
        livereload: {
          options: {
            open: true,
            middleware: function (connect) {
              return [
                connect.static('.tmp'),
                // connect().use(
                //   '/bower_components',
                //   connect.static('./bower_components')
                // ),
                connect().use(
                  '/app/styles',
                  connect.static('./app/styles')
                ),
                connect.static(appConfig.app)
              ];
            }
          }
        },
        test: {
          options: {
            port: 9001,
            middleware: function (connect) {
              return [
                connect.static('.tmp'),
                connect.static('test'),
                // connect().use(
                //   '/bower_components',
                //   connect.static('./bower_components')
                // ),
                connect.static(appConfig.app)
              ];
            }
          }
        },
        dist: {
          options: {
            open: true,
            base: '<%= innoplexus.dist %>'
          }
        }
      },
  
      // Make sure there are no obvious mistakes
      jshint: {
        options: {
          jshintrc: '.jshintrc',
          reporter: require('jshint-stylish')
        },
        all: {
          src: [
            'Gruntfile.js',
            '<%= innoplexus.app %>/**/*.js'
          ]
        },
        test: {
          options: {
            jshintrc: 'test/.jshintrc'
          },
          src: ['test/spec/**/*.js']
        }
      },
  
      // Make sure code styles are up to par
      jscs: {
        options: {
          config: '.jscsrc',
          verbose: true
        },
        all: {
          src: [
            'Gruntfile.js',
            '<%= innoplexus.app %>/**/*.js'
          ]
        },
        test: {
          src: ['test/spec/**/*.js']
        }
      },
  
      // Empties folders to start fresh
      clean: {
        dist: {
          files: [{
            dot: true,
            src: [
              '.tmp',
              '<%= innoplexus.dist %>/{,*/}*',
              '!<%= innoplexus.dist %>/.git{,*/}*'
            ]
          }]
        },
        server: '.tmp'
      },
      includeSource: {
        options: {
          basePath: 'inno',
          baseUrl: '/',
        },
        server: {
          files: {
            '.tmp/index.html': '<%= innoplexus.app %>/index.html'
          }
        },
        dist: {
          files: {
            '<%= innoplexus.dist %>/index.html': '<%= innoplexus.app %>/index.html'
          }
        }
      },
      // Add vendor prefixed styles
      // postcss: {
      //   options: {
      //     processors: [
      //       require('autoprefixer-core')({browsers: ['last 1 version']})
      //     ]
      //   },
      //   server: {
      //     options: {
      //       map: true
      //     },
      //     files: [{
      //       expand: true,
      //       cwd: '.tmp/styles/',
      //       src: '{,*/}*.css',
      //       dest: '.tmp/styles/'
      //     }]
      //   },
      //   dist: {
      //     files: [{
      //       expand: true,
      //       cwd: '.tmp/styles/',
      //       src: '{,*/}*.css',
      //       dest: '.tmp/styles/'
      //     }]
      //   }
      // },
  
      // Automatically inject Bower components into the app
      // wiredep: {
      //   app: {
      //     src: ['<%= innoplexus.app %>/index.html'],
      //     ignorePath:  /\.\.\//
      //   },
      //   test: {
      //     devDependencies: true,
      //     src: '<%= karma.unit.configFile %>',
      //     ignorePath:  /\.\.\//,
      //     fileTypes:{
      //       js: {
      //         block: /(([\s\t]*)\/{2}\s*?bower:\s*?(\S*))(\n|\r|.)*?(\/{2}\s*endbower)/gi,
      //           detect: {
      //             js: /'(.*\.js)'/gi
      //           },
      //           replace: {
      //             js: '\'{{filePath}}\','
      //           }
      //         }
      //       }
      //   },
      //   task: {
      //       exclude: [ /modernizr/, /html5shiv/, /respond/ ],
      //       src: ['public/index.html'],
      //       fileTypes: {
      //           html: {
      //               block: /(([ \t]*)<!--\s*bower:*(\S*)\s*-->)(\n|\r|.)*?(<!--\s*endbower\s*-->)/gi,
      //               detect: {
      //                   js: /<script.*src=['"]([^'"]+)/gi,
      //                   css: /<link.*href=['"]([^'"]+)/gi
      //               },
      //               replace: {
      //                   js: '<script src="/{{filePath}}"></script>',
      //                   css: '<link rel="stylesheet" href="/{{filePath}}" />'
      //               }
      //           }
      //       }
      //   }
      // },
      // sass: {
      //   src: ['<%= innoplexus.app %>/styles/{,*/}*.{scss,sass}'],
      //   //ignorePath: /(\.\.\/){1,2}bower_components\//
      // },
      // sass: {
      //     options: {
      //         sourceMap: true
      //     },
      //     dist: {
      //         files: {
      //             'app/styles/main.css': 'app/styles/**/*.{scss,sass}'
      //         }
      //     }
      // },
      sass: {
          options: {
              includePaths: [
                  'bower_components'
              ]
          },
          dist: {
              files: [{
                  expand: true,
                  cwd: '<%= innoplexus.app %>/assets/styles',
                  src: ['*.scss'],
                  dest: '.tmp/styles',
                  ext: '.css'
              }]
          },
          server: {
              files: [{
                  expand: true,
                  cwd: '<%= innoplexus.app %>/assets/styles',
                  src: ['*.scss'],
                  dest: '.tmp/styles',
                  ext: '.css'
              }]
          }
      },
      jade: {
              // Move the compiled .html files from .tmp/ to dist/
          dist: {
              files: [{
                  expand: true,
                  cwd: '.tmp/',
                  src: ['**/*.html'], // Actual pattern(s) to match.
                  dest: '<%= innoplexus.dist %>'
              }]
          },
          // Compile .jade files in app/views/ to .tmp/
          compile: {
              options: {
                  pretty: true,
                  data: {
                      debug: false
                  }
              },
              files: [{
                  expand: true, // Enable dynamic expansion.
                  cwd: '<%= innoplexus.app %>/{,*/}*/views', // Src matches are relative to this path.
                  src: '*.jade', // Actual pattern(s) to match.
                  dest: '.tmp/', // Destination path prefix.
                  ext: '.html' // Dest filepaths will have this extension.
              }]
          }
      },
  
      // Compiles Sass to CSS and generates necessary files if requested
      // compass: {
      //   options: {
      //     sassDir: '<%= innoplexus.app %>/styles',
      //     cssDir: '.tmp/styles',
      //     generatedImagesDir: '.tmp/images/generated',
      //     imagesDir: '<%= innoplexus.app %>/images',
      //     javascriptsDir: '<%= innoplexus.app %>/scripts',
      //     fontsDir: '<%= innoplexus.app %>/styles/fonts',
      //     importPath: './bower_components',
      //     httpImagesPath: '/images',
      //     httpGeneratedImagesPath: '/images/generated',
      //     httpFontsPath: '/styles/fonts',
      //     relativeAssets: false,
      //     assetCacheBuster: false,
      //     raw: 'Sass::Script::Number.precision = 10\n'
      //   },
        // dist: {
        //   options: {
        //     generatedImagesDir: '<%= innoplexus.dist %>/images/generated'
        //   }
        // },
        // server: {
        //   options: {
        //     sourcemap: true
        //   }
        // },
  
      // Renames files for browser caching purposes
      filerev: {
        dist: {
          src: [
            '<%= innoplexus.dist %>/**/*.js',
            '<%= innoplexus.dist %>/assets/styles/{,*/}*.css',
            '<%= innoplexus.dist %>/assets/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
            '<%= innoplexus.dist %>/assets/fonts/*'
          ]
        }
      },
  
      // Reads HTML for usemin blocks to enable smart builds that automatically
      // concat, minify and revision files. Creates configurations in memory so
      // additional tasks can operate on them
      useminPrepare: {
        //html: '<%= innoplexus.app %>/index.html',
        html: '<%= innoplexus.dist %>/index.html',
        options: {
          dest: '<%= innoplexus.dist %>',
          flow: {
            html: {
              steps: {
                js: ['concat', 'uglifyjs'],
                css: ['cssmin']
              },
              post: {}
            }
          }
        }
      },
  
      // Performs rewrites based on filerev and the useminPrepare configuration
      usemin: {
        html: ['<%= innoplexus.dist %>/{,*/}*.html'],
        css: ['<%= innoplexus.dist %>/assets/styles/{,*/}*.css'],
        js: ['<%= innoplexus.dist %>/**/*.js'],
        options: {
          assetsDirs: [
            '<%= innoplexus.dist %>',
            '<%= innoplexus.dist %>/assets/images',
            '<%= innoplexus.dist %>/assets/styles'
          ],
          patterns: {
            js: [[/(images\/[^''""]*\.(png|jpg|jpeg|gif|webp|svg))/g, 'Replacing references to images']]
          }
        }
      },
  
      // The following *-min tasks will produce minified files in the dist folder
      // By default, your `index.html`'s <!-- Usemin block --> will take care of
      // minification. These next options are pre-configured if you do not wish
      // to use the Usemin blocks.
      cssmin: {
        dist: {
          files: {
            '<%= innoplexus.dist %>/assets/styles/main.css': [
              '.tmp/styles/{,*/}*.css'
            ]
          }
        }
      },
      uglify: {
        dist: {
          files: {
            '<%= innoplexus.dist %>/scripts/scripts.js': [
              '<%= innoplexus.dist %>/scripts/scripts.js'
            ]
          }
        }
      },
      concat: {
        dist: {}
      },
  
      // imagemin: {
      //   dist: {
      //     files: [{
      //       expand: true,
      //       cwd: '<%= innoplexus.app %>/images',
      //       src: '{,*/}*.{png,jpg,jpeg,gif}',
      //       dest: '<%= innoplexus.dist %>/images'
      //     }]
      //   }
      // },
  
      // svgmin: {
      //   dist: {
      //     files: [{
      //       expand: true,
      //       cwd: '<%= innoplexus.app %>/images',
      //       src: '{,*/}*.svg',
      //       dest: '<%= innoplexus.dist %>/images'
      //     }]
      //   }
      // },
  
      htmlmin: {
        dist: {
          options: {
            // collapseWhitespace: true,
            // conservativeCollapse: true,
            // collapseBooleanAttributes: true,
            // removeCommentsFromCDATA: true
          },
          files: [{
            expand: true,
            cwd: '<%= innoplexus.dist %>',
            src: ['*.html'],
            dest: '<%= innoplexus.dist %>'
          }]
        }
      },
  
      ngtemplates: {
        dist: {
          options: {
            module: 'innoApp',
            htmlmin: '<%= htmlmin.dist.options %>',
            usemin: 'scripts/scripts.js'
          },
          cwd: '<%= innoplexus.app %>',
          src: 'views/{,*/}*.html',
          dest: '.tmp/templateCache.js'
        }
      },
  
      // ng-annotate tries to make the code safe for minification automatically
      // by using the Angular long form for dependency injection.
      ngAnnotate: {
        dist: {
          files: [{
            expand: true,
            cwd: '.tmp/concat/scripts',
            src: '*.js',
            dest: '.tmp/concat/scripts'
          }]
        }
      },
  
      // Replace Google CDN references
      cdnify: {
        dist: {
          html: ['<%= innoplexus.dist %>/*.html']
        }
      },
  
      // Copies remaining files to places other tasks can use
      copy: {
        dist: {
          files: [{
            expand: true,
            dot: true,
            cwd: '<%= innoplexus.app %>',
            dest: '<%= innoplexus.dist %>',
            src: [
              '*.{ico,png,txt}',
              '*.html',
              'assets/images/{,*/}*.{webp}',
              'assets/fonts/{,*/}*.*'
            ]
          }, {
            expand: true,
            cwd: '.tmp/images',
            dest: '<%= innoplexus.dist %>/images',
            src: ['generated/*']
          }, {
            expand: true,
            cwd: '.',
            src: 'bower_components/bootstrap-sass-official/assets/fonts/bootstrap/*',
            dest: '<%= innoplexus.dist %>'
          }]
        },
        styles: {
          expand: true,
          cwd: '<%= innoplexus.app %>/styles',
          dest: '.tmp/styles/',
          src: '{,*/}*.css'
        }
      },
  
      // Run some tasks in parallel to speed up the build process
      // concurrent: {
      //   server: [
      //     'sass'
      //   ],
      //   test: [
      //     'sass'
      //   ],
      //   dist: [
      //     'sass:dist',
      //     //'imagemin',
      //     //'svgmin'
      //   ]
      // },
      concurrent: {
          server: [
              'sass:server',
              'copy:styles',
              'jade'
          ],
          test: [
              'copy:styles'
          ],
          dist: [
              'sass',
              'copy:styles',
              'imagemin',
              'svgmin'
          ]
      },
  
      // Test settings
      karma: {
        unit: {
          configFile: 'test/karma.conf.js',
          singleRun: true
        }
      }
    });
  
  
    grunt.registerTask('serve', 'Compile then start a connect web server', function (target) {
      if (target === 'dist') {
        return grunt.task.run(['build', 'connect:dist:keepalive']);
      }
  
      grunt.task.run([
        'clean:server',
        //'wiredep',
        'concurrent:server',
        // 'postcss:server',
        'sass',
        'jade',
        'includeSource',
        'connect:livereload',
        'watch'
      ]);
    });
  
    grunt.registerTask('server', 'DEPRECATED TASK. Use the "serve" task instead', function (target) {
      grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
      grunt.task.run(['serve:' + target]);
    });
  
    grunt.registerTask('test', [
      'clean:server',
      //'wiredep',
      'concurrent:test',
      'sass',
      'jade',
      'connect:test',
      'karma'
    ]);
  
    grunt.registerTask('build', [
      'clean:dist',
      //'wiredep',
      'useminPrepare',
      'concurrent:dist',
      //'postcss',
      'includeSource:dist',
      'sass',
      'jade',
      'ngtemplates',
      'concat',
      'ngAnnotate',
      'copy:dist',
      'cdnify',
      'cssmin',
      'uglify',
      'filerev',
      'usemin',
      'htmlmin'
    ]);
  
    grunt.registerTask('default', [
      'newer:jshint',
      'newer:jscs',
      'test',
      'build'
    ]);
  };
  