/**
* @todo adicionar a classe 'hover' aos "abridores" e não remover elas ao levar o mouse aos subitens
* @todo fazer funfar o menu horizontal
* @todo verificar pq não funfa com mais de um menu JSON com vários submenus
*/

/*nlog = 0;
function log(msg)
{
       $('#log').html(nlog+'..'+msg+"<br/>"+$('#log').html());
       //$('#log').html($('#log').html()+nlog+'..'+msg+"<br/>");
       nlog = nlog+1;
}

function write(code)
{
       $('#json').html($('#json').html()+code);
}
*/

//funcao que busca o valor no array
Array.prototype.have = function(v) {
       if(this.length==0) return false;

       for(var i=0; i<this.length; i=i+1)
       {
               if(this[i]==v) return true;
       }

       return false;
};

//funcao que retorna a chave de um indice procurando pelo valor
Array.prototype.search = function(v) {
       for(var i=0; i<this.length; i=i+1)
       {
               if(this[i]==v) return i;
       }
       return false;
};

function fullClearTimeout(TIdList)
{
       for(var i=0;i<TIdList.length; i++)
       {
               clearTimeout(TIdList[i]);
       }
};

jQuery.submenu = {
       items2Hide: [],
       timeOut: 100,
       lastTID: [],
       JSONCreated: false,
       JSONElCreated: [],
       JSONId: 0, //variavel pra geracao dos IDs quando passado um JSON
       
       //registra as acoes de abrir o submenu
       register: function(menu, opts, hide) {
           //registrando as opcoes no proprio elemento
           var subMenuOpts = { sub: opts.el, options: opts };
           //alert(menu.id+'>'+subMenuOpts.options.style);
           $(menu)[0].subMenu = subMenuOpts;
               
           $(menu).hover(
               //abre submenu
               function() {
                   jQuery.submenu.show(this, hide);
               },
               //fecha submenu
               function() {
                   jQuery.submenu.hidden(this);
               }
               );


           //fazendo com q o submenu não seja escondido ao colocar o mouse sobre ele
               $(opts.el).hover(function() {
                               fullClearTimeout(jQuery.submenu.lastTID);
                               //log('apagado >'+jQuery.submenu.lastTID);
                           },
                           function() {
                               //jQuery.submenu.hideAll();
                               //log(opts.el);
                                   //jQuery.submenu.lastTID = setTimeout(function() {
                                   jQuery.submenu.lastTID.push(setTimeout(function() {
                                       jQuery.submenu.hideAll();
                                   }, jQuery.submenu.timeOut));
                                   //log('hideAll >'+jQuery.submenu.lastTID);
                       }
                       )
                       .hide();
       },
       
       //funcao q exibe os submenus de um item
       show: function(el, hide) {
           var oSub = el.subMenu;
           var p = this.getPositions(el, oSub.options.style);
           
           //sumindo com os sub abertos (isso muda qdo for usado o JSON (quando existerem filhos de filhos) )
           if(hide=='hide') this.hideAll();
           
           //registrando quais submenus esconder quando tirar o mouse
           this.items2Hide.push(oSub.sub);
           
           //alert(el.id+'>'+oSub.options.style);
           
           //log('exibindo > '+oSub.sub+' | '+el.id+' - '+p.top+'-'+p.left);
           //log(oSub.sub+'>'+$(oSub.sub).css('position'));
		   if (oSub.options.style == 'v'){
			   topPosition = oSub.options.topPosition;
			   leftPosition = oSub.options.leftPosition;
		   }else{
			   topPosition = 0;
			   leftPosition = 0;
		   }
		   $(oSub.sub)
			   .css({
				   'position': 'absolute',
						   'top': (p.top + topPosition)+'px',
				   'left': (p.left - leftPosition)+'px',
				   'z-index': 1000
				   })
			   .show();
       //log(oSub.sub+'>'+$(oSub.sub).css('position'));
       },
       
       hideAll: function() {
           fullClearTimeout(jQuery.submenu.lastTID);
           if(this.items2Hide.length>0)
           {
               for(var i=this.items2Hide.length-1; i>=0; i--)
               {
                   this.hideNow(this.items2Hide[i]);
               }
               
               this.items2Hide = [];
           }
       },
       
       //funcao q esconde os submenus de um item
       hidden: function(el) {
           var oSub = el.subMenu;

               //log('.hidden = criando ID>'+oSub.sub);
           jQuery.submenu.lastTID.push(setTimeout(function() {
               jQuery.submenu.hideNow(oSub.sub);
           }, this.timeOut));
           //log('hidden = ID >>'+jQuery.submenu.lastTID+' | '+oSub.sub);
       },
       
       hideNow: function(el) {
           //alert(onde);
           //var oSub = el.subMenu;
           //$(oSub.sub).hide();
           //jQuery.submenu.items2Hide.splice(jQuery.submenu.items2Hide.search(oSub.sub),1);
           //log('escondendo >'+jQuery.submenu.lastTID);
           $(el).hide();
           jQuery.submenu.items2Hide.splice(jQuery.submenu.items2Hide.search(el),1);
       },
       
       //retorna as posicoes onde o submenu devera ser aberto
       getPositions: function(el, tipo) {
           p = $(el).offset();
           //alert(p.toSource());
           if(tipo=='v')
           {
               return { top: p.top, left: p.left+p.width };
           }
           else if(tipo=='h')
           {
               return { top: p.top+p.height, left: p.left };
           }
       },
       
       //interpreta o JSON e cria os menus
       create: function(json, opts) {
               jQuery.submenu.JSONCompile(json, '');
               
               //registrando todos (menos o primeiro) os submenus criados pela compilacao do JSON
               for(var i=1; i<jQuery.submenu.JSONElCreated.length; i++)
               {
                   var nOpts = opts;
                   nOpts.el = '#subMenuJson'+i;
                   
                   var link = '#subMenuJsonOpen'+(i-1);
                   
                   //alert($('#subMenuJsonOpen'+i)[0]);
                   jQuery.submenu.register( $(link)[0], nOpts, 'nohide');
               }
       },
       
       JSONCompile: function(json, html) {
           if(json.submenus.length>0)
           {
               html += '<div id="subMenuJson'+jQuery.submenu.JSONId+'" class="submenuJqueryLista"><ul>\n';

                       //adicionando aos elementos criados pelo JSON
                       jQuery.submenu.JSONElCreated[jQuery.submenu.JSONId] = "subMenuJson"+jQuery.submenu.JSONId;

               jQuery.submenu.JSONId++;

                   for(var i=0; i<json.submenus.length; i++) {
                       html += '<li>\n';

                               if(json.submenus[i].item.link)
                               {
                                       html += '<a href="'+json.submenus[i].item.link+'"';


                                       if(json.submenus[i].item.target)
                                           html += ' target="'+json.submenus[i].item.target+'"';

                                       html += '>'+json.submenus[i].item.label+'</a>';
                               }

                               if(json.submenus[i].item.submenus)
                               {
                                   var JSONId = jQuery.submenu.JSONId - 1;
                                   html += '<a href="#" id="subMenuJsonOpen'+JSONId+'" class="submenuJqueryWS">'+json.submenus[i].item.label+'</a>';
                                   
                                   html += "<\/li>\n";
                                   html += "<\/ul></div>\n";
                                   
                                   jQuery.submenu.JSONCompile(json.submenus[i].item, '');
                               }

                               html += "<\/li>\n";
                   }
                   html += "<\/ul></div>\n";


                       if(!jQuery.submenu.JSONCreated)
                       {
                           if(jQuery('#submenuJqueryContainer')[0]==undefined)
                                       jQuery('body').append('<div id="submenuJqueryContainer"></div>');
                                       
                               jQuery('#submenuJqueryContainer').append(html);
                       }
               }
       }
};

jQuery.fn.addSubMenu = function(submenu, opts)
{
       subOptions = { menuHoverClass: opts.hoverClass, topPosition: opts.topPosition, leftPosition: opts.leftPosition};
       
       if(typeof submenu == "object")
       {
           //interpreta o JSON e cria os elementos
           subOptionsJson = subOptions;
       	   subOptionsJson.style = 'v';
           jQuery.submenu.create(submenu, subOptionsJson);
           sub = '#subMenuJson0';
           
           subOptions.el = sub;
       }
       else if(typeof submenu == "string")
       {
           //associa um elemento como submenu
               sub = submenu;
               
               subOptions.el = sub;
       }

       subOptions.style = opts.style;
       
       this.each(
           function()
           {
                       jQuery.submenu.register( this, subOptions , 'hide');
           }
       );
       
       return this;
};