/*
 * prefix a css file
 * -----------------------
 * Copyright (c) 2013 Anas Nakawa
 * Licensed under the MIT license.
 */

'use strict';

// --------------------------
// attempt to process all css
// selectors, and prefix them
// with a given string
// --------------------------

// external modules
var rework = require( 'rework' )
, str = require( 'underscore.string' )

// Class definition
, Prefixer = function( file, options ) {
  this.file = file;
  this.options = options;
};

Prefixer.registerRuleHandler = function( ruleName, handler ) {
  Prefixer.prototype[ ruleName + 'RuleHandler' ] = handler;
}

Prefixer.prototype.processRule = function( rule ) {
  return this.getRuleHandler( rule ).call( this, rule );
};

Prefixer.prototype.getRuleHandler = function( rule ) {
  if( rule && rule.type ) {
    return this[ rule.type + 'RuleHandler' ];  
  }
};

Prefixer.prototype.isHandlerExist = function( rule ) {
  return typeof this.getRuleHandler( rule ) === 'function';
};

Prefixer.prototype.processFile = function() {
  var self = this;
  return function( styles ) {
    styles.rules.forEach( function( rule ) {
      // call out our rule handler
      if( self.isHandlerExist( rule ) ) {
        self.processRule( rule );
      }
    });   
  }
};

Prefixer.prototype.processName = function( name ) {
  if( str[ this.options.processName ] == null ) {
    throw new Error( 'could not find a method for the option processName: ' + this.options.processName );
  }

  return str[ this.options.processName ]( name );
};

Prefixer.prototype.mixin = function( propName ) {
  var self = this
  , temp   = {}
  , noop   = function() {}
  , fn     = function( type ) {
    var prop = {};
    prop[ propName ] = self.options.prefix + self.processName( type )
    return prop;
  };

  temp[ '-webkit-' + propName ] = noop;
  temp[    '-moz-' + propName ] = noop;
  temp[     '-ms-' + propName ] = noop;
  temp[      '-o-' + propName ] = noop;
  temp[              propName ] = fn;

  return temp;
};

// rule handlers
// -------------
Prefixer.registerRuleHandler( 'rule', function( rule ) {
  // prefixing class names
  for( var i = 0, len = rule.selectors.length; i < len; i++ ) {
    rule.selectors[ i ] = this.processName( rule.selectors[ i ] ).split( '.' ).join( '.' + this.options.prefix );
  }
});

Prefixer.registerRuleHandler( 'keyframes', function( rule ) {
  // prefixing keyframe names
  rule.name = this.options.prefix + this.processName( rule.name );
});


module.exports = function( file, options ) {
  var prefixerInstance = new Prefixer( file, options )
  , reworkInstance = rework( file );

  reworkInstance
    .use( prefixerInstance.processFile() )
    .use(
      rework.mixin(
        prefixerInstance.mixin( 'animation-name' )
      )
    )
    .use(
      rework.prefix( 'animation-name', options.vendor )
    );

  return reworkInstance.toString();

}
@@ -477,24 +477,144 @@
 ptions;%0A%7D;%0A%0A
+// Helper method to register prefixer handler%0A//%0A// * **param:** %7Bstring%7D   ruleName%0A// * **param:** %7Bfunction%7D handler%0A
 Prefixer.reg
@@ -727,16 +727,77 @@
 ler;%0A%7D%0A%0A
+// call target rule handler%0A//%0A// * **param:** %7Bobject%7D rule%0A
 Prefixer
@@ -893,32 +893,102 @@
 is, rule );%0A%7D;%0A%0A
+// get target rule handler if exist%0A//%0A// * **param:** %7Bobject%7D rule %0A
 Prefixer.prototy
@@ -1102,32 +1102,114 @@
 r' %5D;  %0A  %7D%0A%7D;%0A%0A
+// check wither a handler exist for current rule%0A//%0A// * **param:** %7Bobject%7D rule%0A
 Prefixer.prototy
@@ -1307,24 +1307,81 @@
 ction';%0A%7D;%0A%0A
+// Prefixer main method that will iterate over all rules%0A
 Prefixer.pro
@@ -1642,24 +1642,114 @@
    %0A  %7D%0A%7D;%0A%0A
+// process a given name with %60undersocre.string%60 methods%0A//%0A// * **param:** %7Bstring%7D name%0A
 Prefixer.pro
@@ -2003,16 +2003,191 @@
  );%0A%7D;%0A%0A
+// generate a mixin specific for %60rework%60 for a given property%0A// without any vendor prefix%0A//%0A// * **param:** %7Bstring%7D propName   css property name to generate the mixin for%0A
 Prefixer
@@ -3525,9 +3525,10 @@
 ing();%0A%0A
-
 %7D
+%0A

Update prefixer.js