// The youngisrael-stl.org jquery basic plugins
// uojs for automating unobtrusive javascript
// dom and individual elements for DOM creation

(function($){

/**
uojs:

Implements unobtrusive Javascript unobtrusively. selects all elements 
with a class 'make_foo', applies the foo() plugin to them, then changes 
the class to 'made_foo'.
Options can be added by making the class 'make_foo_bar'; where 
$.fn.foo.bar is assigned (in the javascript code) to the options object.
Assumes all plugins take at most one argument, an object of options. If 
there is no underline after
the class name, looks for a member of the element e.foo and uses that 
as the argument to foo. (e.foo must have been added by one of the 
metadata plugins.)
Thus:
<div class="make_Slider_indicator">
	<div class="indicator" id="indicator1">&nbsp;</div>
</div>
and in a <script> :
$.fn.Slider.indicator = {accept :  '.indicator', opacity:  0.8, values: 
[[290,0]]}

or, using metaobjects:
<div class="make_Slider">
       <object class="metaobject">
            <param name="Slider" value="{accept: '.indicator', opacity: 0.8, values: [[290,0]]}" />
       </object>
	<div class="indicator" id="indicator1">&nbsp;</div>
</div>

or, using metadata:
<div class="make_Slider {Slider: {accept : '.indicator', opacity: 0.8, values: [[290,0]]} }">
	<div class="indicator" id="indicator1">&nbsp;</div>

</div>
*/

$.fn.uojs = function(){
  $('[@className*=make_]').each(function(){
    while (m = $.fn.uojs.re.exec(this.className)){
      // m[2] is the whole "class name", m[3] is the plugin name, m[5] is the argument
      var plugin = $.fn[m[3]];
      var options = m[5] && plugin[m[5]] || this[m[3]];
      plugin.call($(this), options);
      this.className = this.className.replace(m[2], 'made_'+m[3]);
     } // for
   }); // each
 }; // uojs
$.fn.uojs.re = /(^|\s)(make_([A-Za-z0-9\$]*)(_([A-Za-z0-9\$]*))?)(\s|$)/;
$(function(){$().uojs()}); // just do it

// DOM creation code, based on http://mg.to/2006/02/27/easy-dom-creation-for-jquery-and-prototype
// and the subsequent comments.
// A simple table would be:
// $.dom (
//   'table',{Class: 'table-class'},['tbody',{}, [
//     'tr',{}, [
//       'td',{}, ['r1c1'],
//       'td',{style: {color: 'red'}}, ['r1c2']
//     ],
//     'tr',{}, [
//       'td',{}, ['r2c2'],
//       'td',{}, ['r1c2: ', 'a', {href: 'whatever.html', title='link'}, ['Link Text']]]
//     ]
//   ]
// );
// You can use already-created HTMLElements and jQuery's in there:
// img = $.dom('img', {src:'foo.gif'});
// div = $.dom('div', {}, [img]);
// creates a div with the image inside. Note that text followed by an object is interpreted as a tagName
// to create, so $.dom('hello', existingObject) gives an error (what you wanted was a textNode 'hello', followed by the
// existing object). You need to put one of them into an array by itself:
// $.dom('hello', [existingObject]);
// and it generates a jQuery object, so it's chainable
$.dom = function(){
  var result = $([]), e;
  for (var i = 0; i < arguments.length; ++i){
    if (typeof arguments[i] == 'string'){
      // a string is either a text literal or a tag name of an element.
      // distinguish by the following argument; a tag name will be followed by an Object
      if (arguments[i+1] && arguments[i+1].constructor == Object){
        e = $(document.createElement(arguments[i])).
          attr (arguments[++i]).css(arguments[i].style || {}); // incorporate the attributes Object
        // append children if the next argument is an array
        if (arguments[i+1] && arguments[i+1].constructor == Array) e.append($.dom.apply(null, arguments[++i]));
      }else{
        e = document.createTextNode(arguments[i]);
      }
    }else if (typeof arguments[i] == 'number'){
      e = document.createTextNode(arguments[i]+'');
    }else if (arguments[i].constructor == Array){
      // process the array
      e = $.dom.apply(null, arguments[i]);
    }else{
      // Something else . Let jQuery deal with it
      e = arguments[i];
    } // if
    result = result.add(e);
  }  // for
  return result;
}; // dom

// predefine some tags, to use as $.P('text') or $.SPAN({Class: 'myclass'}, [child, child])
$.dom.createTag = function(tag){
  $[tag.toUpperCase()] = function(){
    if (arguments.length == 0) return $.dom(tag,{});
    attr = (arguments[0].constructor == Object) ? [].shift.call(arguments) : {};
    return $.dom(tag,attr, [].slice.call(arguments,0));
  }
}; // dom.createTag

$.each(['a', 'br', 'button', 'canvas', 'div', 'fieldset', 'form',
        'h1', 'h2', 'h3', 'hr', 'img', 'input', 'label', 'legend',
        'li', 'ol', 'optgroup', 'option', 'p', 'pre', 'select',
        'span', 'strong', 'table', 'tbody', 'td', 'textarea',
        'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'style', 'script' ],
   function (i,e){$.dom.createTag(e)});

// Return a simple image-button, with hover and active (mousedown) image changes
$.imgButton = function (src, hoverSrc, activeSrc){
  hoverSrc = hoverSrc ? hoverSrc : src;
  activeSrc = activeSrc ? activeSrc : hoverSrc;
  return $.dom ('img', {src: src}).
    hover (function(){this.src=hoverSrc}, function(){this.src=src}).
    mousedown (function(){this.src=activeSrc}).
    mouseup (function(){this.src=hoverSrc});    
}; //imgButton

// simple way to encode HTML entities (turn 'a < b' into 'a &lt; b')
$.dom.htmlencode = function(text){
  return $.dom('span',{}, [text]).html();
};

// simple way to decode HTML entities (turn 'a &lt; b' into 'a < b')
$.dom.htmldecode = function(text){
  return $.dom('span',{}).html(text).text();
};


})(jQuery);

