( function( $ ){
   $.prompt = function( message, options ){
      options = $.extend( {
      }
      , $.prompt.defaults, options );
      $.prompt.currentPrefix = options.prefix;
      var ie6 = ( $.browser.msie && $.browser.version < 7 );
      var $body = $( document.body );
      var $window = $( window );
      options.classes = $.trim( options.classes );
      if( options.classes != '' )options.classes = ' ' + options.classes;
      var msgbox = '<div class="'+options.prefix+'box'+options.classes+'" id="'+options.prefix+'box">';
      if( options.useiframe && ( ( $( 'object, applet' ).length > 0 ) || ie6 ) ){
         msgbox += '<iframe src="javascript:false;" style="display:block;position:absolute;z-index:-1;" class="'+options.prefix+'fade" id="'+options.prefix+'fade"></iframe>';
      }
      else{
         if( ie6 ){
            $( 'select' ).css( 'visibility', 'hidden' );
         }
         msgbox += '<div class="'+options.prefix+'fade" id="'+options.prefix+'fade"></div>';
      }
      msgbox += '<div class="'+options.prefix+'" id="'+options.prefix+'"><div class="'+options.prefix+'container"><div class="';
      msgbox += options.prefix + 'close">X</div><div id="' + options.prefix + 'states"></div>';
      msgbox += '</div></div></div>';
      var $jqib = $( msgbox ).appendTo( $body );
      var $jqi = $jqib.children( '#' + options.prefix );
      var $jqif = $jqib.children( '#' + options.prefix + 'fade' );
      if( message.constructor == String ){
         message = {
            state0 : {
               html : message, buttons : options.buttons, focus : options.focus, submit : options.submit
            }
         }
         ;
      }
      var states = "";
      $.each( message, function( statename, stateobj ){
         stateobj = $.extend( {
         }
         , $.prompt.defaults.state, stateobj );
         message[statename] = stateobj;
         states += '<div id="'+options.prefix+'_state_'+statename+'" class="'+options.prefix+'_state" style="display:none;"><div class="'+options.prefix+'message">' + stateobj.html + '</div><div class="'+options.prefix+'buttons">';
         $.each( stateobj.buttons, function( k, v ){
            states += '<button name="'+options.prefix+'_'+statename+'_button'+k+'" id="'+options.prefix+'_'+statename+'_button'+k+'" value="'+v+'">' + k + '</button>';
         }
         );
         states += '</div></div>';
      }
      );
      $jqi.find( '#' + options.prefix + 'states' ).html( states ).children( '.' + options.prefix + '_state:first' ).css( 'display', 'block' );
      $jqi.find( '.' + options.prefix + 'buttons:empty' ).css( 'display', 'none' );
      $.each( message, function( statename, stateobj ){
         var $state = $jqi.find( '#' + options.prefix + '_state_' + statename );
         $state.children( '.' + options.prefix + 'buttons' ).children( 'button' ).click( function(){
            var msg = $state.children( '.' + options.prefix + 'message' );
            var clicked = stateobj.buttons[$( this ).text()];
            var forminputs = {
            }
            ;
            $.each( $jqi.find( '#' + options.prefix + 'states :input' ).serializeArray(), function( i, obj ){
               if( forminputs[obj.name] === undefined ){
                  forminputs[obj.name] = obj.value;
               }
               else if( typeof forminputs[obj.name] == Array || typeof forminputs[obj.name] == 'object' ){
                  forminputs[obj.name].push( obj.value );
               }
               else{
                  forminputs[obj.name] = [forminputs[obj.name], obj.value];
               }
            }
            );
            var close = stateobj.submit( clicked, msg, forminputs ); if( close === undefined || close ){
               removePrompt( true, clicked, msg, forminputs );
            }
         }
         );
         $state.find( '.' + options.prefix + 'buttons button:eq(' + stateobj.focus + ')' ).addClass( options.prefix + 'defaultbutton' );
      }
      );
      var ie6scroll = function(){
         $jqib.css( {
            top : $window.scrollTop()
         }
         );
      }
      ;
      var fadeClicked = function(){
         if( options.persistent ){
            var i = 0;
            $jqib.addClass( options.prefix + 'warning' );
            var intervalid = setInterval( function(){
               $jqib.toggleClass( options.prefix + 'warning' );
               if( i ++ > 1 ){
                  clearInterval( intervalid );
                  $jqib.removeClass( options.prefix + 'warning' );
               }
            }
            , 100 );
         }
         else{
            removePrompt();
         }
      }
      ;
      var keyPressEventHandler = function( e ){
         var key = ( window.event ) ? event.keyCode : e.keyCode;
         if( key == 27 ){
            fadeClicked();
         }
         if( key == 9 ){
            var $inputels = $( ':input:enabled:visible', $jqib );
            var fwd = ! e.shiftKey && e.target == $inputels[$inputels.length - 1];
            var back = e.shiftKey && e.target == $inputels[0];
            if( fwd || back ){
               setTimeout( function(){
                  if( ! $inputels )return;
                  var el = $inputels[back === true ? $inputels.length - 1 : 0];
                  if( el )el.focus();
               }
               , 10 );
               return false;
            }
         }
      }
      ;
      var positionPrompt = function(){
         $jqib.css( {
            position : ( ie6 ) ? "absolute" : "fixed", height : $window.height(), width : "100%", top : ( ie6 ) ? $window.scrollTop() : 0, left : 0, right : 0, bottom : 0
         }
         );
         $jqif.css( {
            position : "absolute", height : $window.height(), width : "100%", top : 0, left : 0, right : 0, bottom : 0
         }
         );
         $jqi.css( {
            position : "absolute", top : options.top, left : "50%", marginLeft : ( ( $jqi.outerWidth() / 2 ) * - 1 )
         }
         );
      }
      ;
      var stylePrompt = function(){
         $jqif.css( {
            zIndex : options.zIndex, display : "none", opacity : options.opacity
         }
         );
         $jqi.css( {
            zIndex : options.zIndex + 1, display : "none"
         }
         );
         $jqib.css( {
            zIndex : options.zIndex
         }
         );
      }
      ;
      var removePrompt = function( callCallback, clicked, msg, formvals ){
         $jqi.remove();
         if( ie6 ){
            $body.unbind( 'scroll', ie6scroll );
         }
         $window.unbind( 'resize', positionPrompt );
         $jqif.fadeOut( options.overlayspeed, function(){
            $jqif.unbind( 'click', fadeClicked );
            $jqif.remove();
            if( callCallback ){
               options.callback( clicked, msg, formvals );
            }
            $jqib.unbind( 'keypress', keyPressEventHandler );
            $jqib.remove();
            if( ie6 && ! options.useiframe ){
               $( 'select' ).css( 'visibility', 'visible' );
            }
         }
         );
      }
      ;
      positionPrompt();
      stylePrompt();
      if( ie6 ){
         $window.scroll( ie6scroll );
      }
      $jqif.click( fadeClicked );
      $window.resize( positionPrompt );
      $jqib.bind( "keydown keypress", keyPressEventHandler );
      $jqi.find( '.' + options.prefix + 'close' ).click( removePrompt );
      $jqif.fadeIn( options.overlayspeed );
      $jqi[options.show]( options.promptspeed, options.loaded );
      $jqi.find( '#' + options.prefix + 'states .' + options.prefix + '_state:first .' + options.prefix + 'defaultbutton' ).focus();
      if( options.timeout > 0 )setTimeout( $.prompt.close, options.timeout );
      return $jqib;
   }
   ;
   $.prompt.defaults = {
      prefix : 'jqi', classes : '', buttons : {
         Ok : true
      }
      , loaded : function(){
      }
      , submit : function(){
         return true;
      }
      , callback : function(){
      }
      , opacity : 0.6, zIndex : 999, overlayspeed : 'slow', promptspeed : 'fast', show : 'fadeIn', focus : 0, useiframe : false, top : "15%", persistent : true, timeout : 0, state : {
         html : '', buttons : {
            Ok : true
         }
         , focus : 0, submit : function(){
            return true;
         }
      }
   }
   ;
   $.prompt.currentPrefix = $.prompt.defaults.prefix;
   $.prompt.setDefaults = function( o ){
      $.prompt.defaults = $.extend( {
      }
      , $.prompt.defaults, o );
   }
   ;
   $.prompt.setStateDefaults = function( o ){
      $.prompt.defaults.state = $.extend( {
      }
      , $.prompt.defaults.state, o );
   }
   ;
   $.prompt.getStateContent = function( state ){
      return $( '#' + $.prompt.currentPrefix + '_state_' + state );
   }
   ;
   $.prompt.getCurrentState = function(){
      return $( '.' + $.prompt.currentPrefix + '_state:visible' );
   }
   ;
   $.prompt.getCurrentStateName = function(){
      var stateid = $.prompt.getCurrentState().attr( 'id' );
      return stateid.replace( $.prompt.currentPrefix + '_state_', '' );
   }
   ;
   $.prompt.goToState = function( state ){
      $( '.' + $.prompt.currentPrefix + '_state' ).slideUp( 'slow' );
      $( '#' + $.prompt.currentPrefix + '_state_' + state ).slideDown( 'slow', function(){
         $( this ).find( '.' + $.prompt.currentPrefix + 'defaultbutton' ).focus();
      }
      );
   }
   ;
   $.prompt.nextState = function(){
      var $next = $( '.' + $.prompt.currentPrefix + '_state:visible' ).next();
      $( '.' + $.prompt.currentPrefix + '_state' ).slideUp( 'slow' );
      $next.slideDown( 'slow', function(){
         $next.find( '.' + $.prompt.currentPrefix + 'defaultbutton' ).focus();
      }
      );
   }
   ;
   $.prompt.prevState = function(){
      var $next = $( '.' + $.prompt.currentPrefix + '_state:visible' ).prev();
      $( '.' + $.prompt.currentPrefix + '_state' ).slideUp( 'slow' );
      $next.slideDown( 'slow', function(){
         $next.find( '.' + $.prompt.currentPrefix + 'defaultbutton' ).focus();
      }
      );
   }
   ;
   $.prompt.close = function(){
      $( '#' + $.prompt.currentPrefix + 'box' ).fadeOut( 'fast', function(){
         $( this ).remove();
      }
      );
   }
   ;
   $.fn.prompt = function( options ){
      if( options == undefined )options = {
      }
      ;
      if( options.withDataAndEvents == undefined )options.withDataAndEvents = false;
      $.prompt( $( this ).clone( withDataAndEvents ).html(), options );
   }
}
 )( jQuery );

