/*
 *  tjs - tiny JavaScript Library
 *  (c) 2010 Konstantin Kirilov. 
 *  tiny is freely distributable under the terms of an MIT-style (X11) license.
 *  tiny has reused, borrowed, or followed up from the following sources:
 *
 *  Prototype JavaScript framework, version 1.6.0.3
 *  (c) 2005-2008 Sam Stephenson
 *  For Prototype details, see the Prototype web site: http://www.prototypejs.org/
 *
*/

/*
    B r i e f   D s c r i p t i o n.

    Global DOM Namespace pollution: only one global name introduced: window.tj$.
    All functionality is packed behind object tj$.

    Only in case if other JS applicaition use this name, there may be a conflict.
    However, in this case, the name tj$ can be changed, just only in one place in the 
    file t.js.

    t.js is a main file. Other are optional. They must be loaded after t.js.
*/
tj$ = {
 
  version : '0.0.5',
  $ : function (id) { return document.getElementById(id); },
  IE : !!window.attachEvent && ! (Object.prototype.toString.call(window.opera) == '[object Opera]'),

  drag : new ( 
           function () {

             //Closure data:
             var that = this;
             var IE = !!window.attachEvent && ! (Object.prototype.toString.call(window.opera) == '[object Opera]');
             var g_MouseEvent = new Object();
             var g_MouseStartX=0;
             var g_MouseStartY=0;
             var g_DragStartX=0;
             var glfDragByMouse=false;
             var glfMoveByMouse=false;
             var movingTile;
             //Closure data end.

             //===============================================================
             // "Drag and drop" helplers
             //---------------------------------------------------------------
             //Additionally in IE, prevents text selection and image dragging:
             var addDragListener = function ( eventType, callBack){
                  if(document.addEventListener){
                      document.addEventListener(eventType, callBack, false);
                  }else if(document.attachEvent){
                      //Purpose: for IE:
                      document.attachEvent("on"+eventType, callBack);
                      document.body.focus(); //in IE: no text selection
                      document.onselectstart=function(){return false;}; //don't let IE to drag an image 
                  }
              };

              var removeDragListener = function ( eventType, callBack ){
                  if(document.removeEventListener){
                       document.removeEventListener( eventType, callBack, false);
                  }else if(document.detachEvent){
                       document.detachEvent("on"+eventType, callBack);
                  }
              };
              //---------------------------------------------------------------
              // "Drag and drop" helplers
              //===============================================================


              //-------------------------------------------------
              // Creates g_MouseEvent object with properties:
              //   x,y
              //   which (number of button clicked)
              //   target
              // If no target or no event exists, g_MouseEvent is null.
              //
              // Credit: Èëüÿ Êàíòîð, 22 ìàÿ 2009,
              // http://javascript.ru/tutorial/events/properties 
              //-------------------------------------------------
              var crossBrowserMouseEvent = function (e){
                 var x,y;
                 e = e || window.event || null;     //window is for IE.
                 if(!e){ g_MouseEvent=null; return null};

                //KVK: we added simplyfied version of typeof(e.pageX) === 'undefined' because not sure will IE7+ return null:
                if (  (e.pageX == null || !e.pageX ) && e.clientX != null ) { 
                   var html = document.documentElement
                   var body = document.body
                   x = e.clientX + (html && html.scrollLeft || body && body.scrollLeft || 0) - (html.clientLeft || 0)
                   y = e.clientY + (html && html.scrollTop  || body && body.scrollTop  || 0) - (html.clientTop  || 0)
                }else{
                   x=e.pageX;
                   y=e.pageY;
                }

                //Button clicks:
                //TODO: better recognition:
                var button;
                if( IE ){
                   if(      e.button == 1 ) {
                            button = 1; 
                   }else if (e.button == 4 ) {
                            button = 2;
                   }else if (e.button == 2 ) {
                            button = 3
                   } 
                }else{
                   button = e.button + 1;
                }
                //Collect job:
                g_MouseEvent.e=e;
                g_MouseEvent.x=x;
                g_MouseEvent.y=y;
                g_MouseEvent.which=button;
                g_MouseEvent.target = e.target || e.srcElement || null;
                if(g_MouseEvent.target==null)g_MouseEvent=null;
                return g_MouseEvent;
             };

             this.mouseEvent = function (e) { return crossBrowserMouseEvent(e); };

             //Test:
             this.showMouseDown = function (e){
                  var ev = crossBrowserMouseEvent(     (e==undefined || e==null)?null:e     );
                  if( ev ) alert( ev.x + ' ' + ev.y + ' ' + ev.which + ' ' + ev.target );
             };

             this.handleMouseDown = function (e){
                  var ev=crossBrowserMouseEvent(     !e  ?  null : e     );
                  g_MouseEvent = ev;
                  if(ev==null)return false;  //Be conservative to avoid text selection feature.
                  t=ev.target;
                  t.ondragstart=function(){return false;};     // prevent text selection (except IE) return false;  //do1L should do at the creation of tag?
                  if(ev.which!=1)return true;                   //Let browser do its job for buttons 2 and 3.

                  if(t.className!="tile")return true;    
                  if(glfDragByMouse)return false; //the event is already handled;
                  glfDragByMouse=true;

                  movingTile=t;

                  g_MouseStartX=ev.x;
                  g_MouseStartY=ev.y;

                  if( !t.style || !t.style.left ) t.style.left = '0px';
                  if( !t.style || !t.style.top ) t.style.top = '0px';

                  g_DragStartX=parseInt(t.style.left);
                  g_DragStartY=parseInt(t.style.top);

                  addDragListener("mousemove", that.handleDragMouseMove);

                  return false;
            }; //this.handleMouseDown = function (e){


            this.handleDragMouseMove = function (e){
                 if(glfMoveByMouse||!glfDragByMouse)return false;
                 var ev=crossBrowserMouseEvent(  (e==undefined && e==null)?null:e  );
                 if(!ev)return;
                 glfMoveByMouse=true;
                 setMove(ev.x, ev.y, movingTile);
                 glfMoveByMouse=false;
            };


            this.handleDragMouseUp = function (e){
                 var ev=crossBrowserMouseEvent(  (e==undefined && e==null)?null:e  );
                 if(!ev)return;
                 if(!glfDragByMouse)return;
                 removeDragListener("mousemove", that.handleDragMouseMove);

                 setMove(ev.x, ev.y, movingTile);

                 glfMoveByMouse=false;  //Redundant for well working move handler.
                 glfDragByMouse=false;
            };


            var setMove = function(evX,evY,tile) {
                 //Resets t.xy to fit move of an image of tile by mouse.
                 var x2DCorner=g_DragStartX+(evX-g_MouseStartX); // mouseStartPositionX;
                 var y2DCorner=g_DragStartY+(evY-g_MouseStartY);
                 var xCornerInteger=x2DCorner-x2DCorner%1.0; //Need for nice status
                 var yCornerInteger=y2DCorner-y2DCorner%1.0;
                 test( "x,y=" + xCornerInteger + ',' + yCornerInteger);
                 
                 movingTile.style.left = xCornerInteger+'px';
                 movingTile.style.top = yCornerInteger+'px';
            }; 

     }) (),  // drag : new ( 

  test : function () { return this.version }

} //tj$ = { ...


//Utilities:

tj$.util =  {
     //
     getDir : function (path) {
             var pos=path.lastIndexOf('/');   
             return pos < 0 ? '' : path.substr(0,pos);
     } 
} //tj$ = { ...




