/**
 *
 * jquery.charactersCounter.js
 * @author: Paulo de Tarso F. M.
 * @version: 1.0
 *
 * Created by Paulo de Tarso F. M. on 2010-12-15.
 *
 * Copyright (c) 2010 Paulo de Tarso F. M. http://www.paulodetarso.com
 *
 * The MIT License (http://www.opensource.org/licenses/mit-license.php)
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 **/
jQuery( function( $ )
{
	$.fn.extend(
	{
		charactersCounter: function( options )
		{

			var defaults = {

				/**
				 *
				 * @var String
				 * Tag utilizada na criação do contador.
				 *
				 * 1) counter: "div" (Padrão)
				 * 2) counter: "qualquer tag"
				 *
				 **/
				counter : 'div',



				/**
				 *
				 * @var String
				 * ID utilizada no contador.
				 *
				 * 1) counterId: "counter" (Padrão)
				 * 2) counterId: "string"
				 *
				 **/
				counterId : 'counter',



				/**
				 *
				 * @var String
				 * Classe utilizada no contador.
				 *
				 * 1) counterClass: "charactersCounter" (Padrão)
				 * 2) counterClass: "string"
				 *
				 **/
				counterClass : 'charactersCounter',



				/**
				 *
				 * @var String
				 * Classe utilizada no contador quando um campo está focado (contador ativo).
				 *
				 * 1) activeClass: "active" (Padrão)
				 * 2) activeClass: "string"
				 *
				 **/
				activeClass : 'active',



				/**
				 *
				 * @var Int
				 * Indica a largura do contador.
				 *
				 * 1) width: null (Padrão)
				 * 2) width: [número inteiro]
				 *
				 **/
				width : null,



				/**
				 *
				 * @var Int
				 * Indica se a largura do contador será igual à largura do campo associado ao contador
				 *
				 * 1) getParentWidth: false (Padrão)
				 * 2) getParentWidth: [true|false]
				 *
				 **/
				getParentWidth : false,



				/**
				 *
				 * @var Int
				 * Indica a quantidade máxima de caracteres do contador.
				 *
				 * 1) limit: 250 (Padrão)
				 * 2) limit: [número inteiro]
				 *
				 **/
				limit : 250,

		
		
				/**
				 *
				 * @var String
				 * Textos exibidos no contador (plural e singular).
				 *
				 * 1) text: { plural: "caracteres restantes", singular: "caracter restante" } (Padrão)
				 * 2) text: { plural: "texto no plural", singular: "texto no singular" }
				 *
				 **/
				text : { plural: 'caracteres restantes', singular: 'caracter restante' }

			};



			/**
			 *
			 * Extende as opções do plugin, caso novos valores tenham sido informadas
			 *
			 **/
			options = $.extend( defaults, options );



			/**
			 *
			 * Cria um "alias" para o objeto que instanciou o novo contador
			 *
			 **/
			$this = $( this );



			/**
			 *
			 * Índice utilizado na montagem dos contadores
			 *
			 **/
			var	index = parseInt( $( options.counter + '.' + options.counterClass ).length, 10 ) + 1;



			/**
			 *
			 * Verifica se já existe algum texto no textarea para mostrar a quantidade desconsiderando esse texto
			 *
			 **/
			var	chars = parseInt( $this.val( ).length, 10 );
				chars = ( options.limit >= chars ) ? ( options.limit - chars ) : 0;



			/**
			 *
			 * Verifica se já existe um contador após o campo. Se existir, o remove
			 *
			 **/
			if( $this.next( options.counter ).length === 1 )
			{
				$this.next( options.counter ).remove( );
			}



			/**
			 *
			 * Prepara o conteúdo HTML do contador
			 *
			 **/
			var	html  = '';
				html += '<' + options.counter + ' class="' + options.counterClass + '" id="' + options.counterId + index + '">';
				html += '	<span class="chars">' + chars + '</span> ' + options.text.plural;
				html += '</' + options.counter + '>';



			/**
			 *
			 * Insere o contador após o elemento
			 *
			 **/
			$( $this ).after( html );



			/**
			 *
			 * Define a largura do contador (apenas se a largura não foi definida anteriormente, no arquivo CSS por exemplo)
			 *
			 **/
			if( options.getParentWidth )
			{
				$( options.counter + '.' + options.counterClass ).css( 'width', $this.outerWidth( ) );
			}
			else if( options.width )
			{
				$( options.counter + '.' + options.counterClass ).css( 'width', options.width );
			}



			/**
			 *
			 * Altera a classe do contador enquanto o textarea é focado
			 *
			 **/
			$this.bind( 'focus', function( )
			{

				if( $( this ).next( ).hasClass( options.counterClass ) )
				{
					$( this ).next( ).addClass( options.activeClass );
				}

			});



			/**
			 *
			 * Remove a classe do contador após remover o foco do textarea
			 *
			 **/
			$this.bind( 'blur', function( )
			{

				if( $( this ).next( ).hasClass( options.counterClass ) )
				{
					$( this ).next( ).removeClass( options.activeClass );
				}

			});



			/**
			 *
			 * Atualiza o contador conforme o usuário digita no campo
			 *
			 **/
			$this.bind( 'keyup', function( )
			{

				var text = $( this ).val( );
				var caracterAtual = 0;

				if( text )
				{
					text = text.substr( 0, options.limit );
					caracterAtual = text.length;
				}


				var caracteresRestantes = options.limit - caracterAtual;



				/**
				 *
				 * Inicia a variável do novo HTML do contador (já atualizado)
				 *
				 **/
				var new_html = '';



				/**
				 *
				 * Atualiza o contador
				 *
				 **/
				if( caracteresRestantes == 1 )
				{

					/**
					 *
					 * Novo HTML do contador (já atualizado)
					 *
					 **/
					new_html = '	<span class="chars">' + caracteresRestantes + '</span> ' + options.text.singular;


					if( $( this ).next( ).hasClass( options.counterClass ) )
					{
						$( this ).next( ).html( new_html );
					}

				}
				else if( caracteresRestantes <= 0 )
				{
					/**
					 *
					 * Novo HTML do contador (já atualizado)
					 *
					 **/
					new_html = '	<span class="chars">0</span> ' + options.text.plural;


					if( $( this ).next( ).hasClass( options.counterClass ) )
					{
						$( this ).next( ).html( new_html );
					}



					/**
					 *
					 * Remove o texto excedente do campo
					 *
					 **/
					$( this ).val( text.substr( 0, options.limit ) );

				}
				else
				{

					/**
					 *
					 * Novo HTML do contador (já atualizado)
					 *
					 **/
					new_html = '	<span class="chars">' + caracteresRestantes + '</span> ' + options.text.plural;


					if( $( this ).next( ).hasClass( options.counterClass ) )
					{
						$( this ).next( ).html( new_html );
					}

				}

			});

		
			return $this;

		}

	});
});



