/**
 * Keyboard instance
 * 
 * @type Object
 * @author shaman.sir 
 */
var keyboard = {
	
	// id-s
	RESIZABLE_ID: 'keyboard-sel',
	BACKGND_ID:   'keyboard-bg',
	KEYSNUM_ID:   'keys-num',
	
	// pixels
	HANDLE_RESIZE_AREA_WIDTH: 20, // distance from the border where resize allowed
	RESIZE_BACK_AREA_WIDTH:   0, // small amout to add to the resized element
	LEFT_PADDING_WIDTH: 17, // 0 to position keyboard at the left border of bg, 17 at place at C1
	MIN_SELECTION_WIDTH: 67, // 0 to allow resizing without minimum
	KBD_DEFAULT_SIZE: 282, // default size for keyboard, may be equal to MIN_SELECTION_WIDTH
    
    BORDER_WIDTH: 2, // 2 borders, 2px both 	
	
	MAX_KEYBOARD_KEYS: 88,
	TOTAL_SEL_KEYS: 85, // total keys for selection
	
	// boolean
	resizingState: false,
	fullKeyboardMode: false,
	
    bodyMovesAffectSelection: true,
	
	// other
	/* keyboardSizeToKeysNumberMap: {
		9:   3,  16:  5,  24:  6,  31:  8,  39:  10, 47:  12, 55:  13,
		62:  15, 69:  17, 77:  18, 84:  20, 92:  22, 98:  24, 106: 25,
		113: 27, 121: 29, 129: 30, 137: 32, 144: 34, 151: 36, 160: 37,
		167: 39, 174: 41, 182: 42, 189: 44, 197: 46, 205: 48, 212: 49,
		220: 51, 226: 53, 235: 54, 241: 56, 250: 58, 257: 60, 265: 61,
		272: 63, 279: 65, 287: 66, 294: 68, 301: 70, 309: 72, 317: 73,
		325: 75, 331: 77, 340: 78, 347: 80, 355: 82, 362: 84, 367: 85
	}, */
	
	/**
	 * Initiates elements
	 */
	init: function(id) {
		var bckgndElm = $('#' + this.BACKGND_ID + '-' + id);
		var selectionElm = $('#' + this.RESIZABLE_ID + '-' + id);
		var keysNumElm = $('#' + this.KEYSNUM_ID + '-' + id);
		
		var maxKbdWidth = bckgndElm.width() - keyboard.LEFT_PADDING_WIDTH
                           - (keyboard.BORDER_WIDTH * 3); // left border, 
                           // right border and one border width more to look 
                           // as selection part
		
		var inputNum = $('#keynum-' + id);
		
		// Some internal functions
		
		/**
		 * Updates the element, containing the number of keys
		 * 
		 * @param {Integer} [hardValue] hard-coded value, if it is required          		 
		 */
        var updateKeysNumFunc = function(hardValue) {
            keysNumElm
                  .css('top',  (selectionElm.position().top + 
                                selectionElm.height()) + 'px') 
                  .css('left', (selectionElm.position().left + 
                                selectionElm.width()) + 'px')
                  .html(hardValue ? hardValue : 
                        keyboard.getKeysNumberFromSelectionWidth(
                                                        selectionElm.width(), maxKbdWidth)); 
			inputNum.val( keyboard.getKeysNumberFromSelectionWidth(
                                                        selectionElm.width(), maxKbdWidth) );
        };
        
        var updateKeyboardSizeFunc = function(useDefaultSize) {   
		    selectionElm		
		      // set position and width using the backrgound element
		      .css('width', useDefaultSize
		                    ? (keyboard.KBD_DEFAULT_SIZE - keyboard.LEFT_PADDING_WIDTH) + 'px' 
                            : ((keyboard.MIN_SELECTION_WIDTH > 0)
		                       ? (keyboard.MIN_SELECTION_WIDTH - keyboard.LEFT_PADDING_WIDTH) + 'px'
		                       : (bckgndElm.width() - keyboard.LEFT_PADDING_WIDTH) + 'px'))
		      .css('top',  /*(bckgndElm[0].y ? bckgndElm[0].y : */
                            Math.round(bckgndElm.position().top)/*)*/ + 'px')
		      .css('left', /*(bckgndElm[0].x ? bckgndElm[0].x : */ 
                            Math.round(bckgndElm.position().left)/*)*/ + 
		                    keyboard.LEFT_PADDING_WIDTH + 'px')
		      .css('background-position', (keyboard.LEFT_PADDING_WIDTH > 0)
		                      ? '-' + (keyboard.LEFT_PADDING_WIDTH + keyboard.BORDER_WIDTH) + 'px 0' : '0 0');
        };	
        
        var updateCoords = function() { 
            updateKeyboardSizeFunc(true);
            updateKeysNumFunc();            
        };	
		
        /**
         * Handles keyboard resize
         * 
         * @param event {Event} jQuery event to take mouse position from
         * @param handledElm {jQuery} jQuery element which delivered the event
         * @param cursorOutside {Boolean} is cursor outside of the selection element
         */
        var resizeKeyboardFunc = function(event, handledElm, cursorOutside,
                                          changeCursorOnlyOnMove) {
            var posData = {
               left: selectionElm.position().left,
               width: selectionElm.width()
            }
            
            var maxWidth = bckgndElm.width() - keyboard.LEFT_PADDING_WIDTH
                           - (keyboard.BORDER_WIDTH * 3); // left border, 
                           // right border and one border width more to look 
                           // as selection part            
          
            if (/*this.bodyMovesAffectSelection ||*/ 
              ((cursorOutside && (event.pageX < (posData.left + posData.width) +  
                                   keyboard.HANDLE_RESIZE_AREA_WIDTH)) ||
              (!cursorOutside && (event.pageX > (posData.left + posData.width) -
                                   keyboard.HANDLE_RESIZE_AREA_WIDTH)))) {
                
                if (keyboard.resizingState || !changeCursorOnlyOnMove) { 
                    //handledElm.css('cursor', 'e-resize'); // change cursor
                } else {                
                    if (changeCursorOnlyOnMove) 
                        handledElm.css('cursor', 'default'); // change cursor
                }
                 
                if (keyboard.resizingState) {
                   var newWidth = (event.pageX - posData.left) + 
                                             keyboard.RESIZE_BACK_AREA_WIDTH;
                   if (newWidth >= (keyboard.MIN_SELECTION_WIDTH - 
                                    (keyboard.fullKeyboardMode ? 0 : keyboard.LEFT_PADDING_WIDTH))) {
                      selectionElm
                        .css('left', Math.round(bckgndElm.position().left) + 
                                    keyboard.LEFT_PADDING_WIDTH + 'px')
                        .css('width', ((newWidth < maxWidth) ? newWidth : maxWidth) + 'px')
                        .css('background-position', (keyboard.LEFT_PADDING_WIDTH > 0)
		                      ? '-' + (keyboard.LEFT_PADDING_WIDTH + keyboard.BORDER_WIDTH) + 'px 0' : '0 0');                        
                      keyboard.fullKeyboardMode = false;
                   }
                   if (newWidth >= (maxWidth + keyboard.LEFT_PADDING_WIDTH)) {
                        selectionElm
                            .css('left', (parseInt(selectionElm.css('left')) -
                                keyboard.LEFT_PADDING_WIDTH + 1) + 'px') // 1px is lost somewhere, so I'm adding it here
                            .css('width', parseInt(selectionElm.css('width')) + 
                                keyboard.LEFT_PADDING_WIDTH + 'px')
                            .css('background-position', '-' + (keyboard.BORDER_WIDTH + 1) + 'px 0');
                        updateKeysNumFunc(keyboard.MAX_KEYBOARD_KEYS); 
                        keyboard.fullKeyboardMode = true;   
                   } else {
                        updateKeysNumFunc();
                   }
                   
                }
            	
            } else {
                 handledElm.css('cursor', 'default'); // return cursor
            }
        }               
        		
        // configuring positioning/logic for markup
        
        // body must handle the mouse up event to revert resizing state also
        $('body')
		      .mouseup(  function(ev) { keyboard.resizingState = false;
                                        // console.log('resizing mode off');                                                 
		                                return true; });
                                                
        if (this.bodyMovesAffectSelection) {
            $('body')		      
		      .mousemove(function(ev) { resizeKeyboardFunc(ev, $(this), true, true);
		                                return true; });           

        }
				
		    bckgndElm		   
		      // resizing state is initalized on mouse down and 
              // switched off on mouse up + disable browser image dragging
		      .mousedown(function(ev) { keyboard.resizingState = true;
                                        // console.log('resizing mode on');               
		                                return false; })
		      .mouseup(  function(ev) { keyboard.resizingState = false; 
                                        // console.log('resizing mode off');		      
		                                return false; })
		      // mouse moving with the mouse button hold allows to resize
		      .mousemove(function(ev) { resizeKeyboardFunc(ev, $(this), true);
		                                return false; });
		      // click allows to resize also 
		   /* .click(function(ev) { console.log('clicked on background');
                                keyboard.resizingState = true;
                                resizeKeyboardFunc(ev, $(this), true);
                                keyboard.resizingState = false;
		                                return false; }); */
		                                
		                                /* alert((bckgndElm[0].y ? bckgndElm[0].y : 
                           Math.round(bckgndElm.position().top)) + 'px');
                           alert((bckgndElm[0].x ? bckgndElm[0].x : 
                            Math.round(bckgndElm.position().left)) + 
		                    this.LEFT_PADDING_WIDTH + 'px'); */
		                                
		    selectionElm		
              // resizing state is initalized on mouse down and 
              // switched off on mouse up + disable browser image dragging
              .mousedown(function(ev) { keyboard.resizingState = true;
                                        // console.log('resizing mode on');              
                                        return false; })
              .mouseup(function(ev) { keyboard.resizingState = false;
                                      // console.log('resizing mode off');              
              	                      return false; })
              // mouse moving with the mouse button hold allows to resize
		          .mousemove(function(ev) { resizeKeyboardFunc(ev, $(this), false);
		                                return false; })
		          // click allows to resize also
		          .click(function(ev) { keyboard.resizingState = true;
                                    resizeKeyboardFunc(ev, $(this), true);
                                    keyboard.resizingState = false;
		                                return false; });
                                    
        bckgndElm.parent().click(function(ev) { keyboard.resizingState = true;
                                    resizeKeyboardFunc(ev, $(this), false);
                                    keyboard.resizingState = false;
		                                return false; });		                                
		
        if ($.browser.safari) selectionElm.css('display', 'none');
              
        //updateCoords();
        
        $(window).bind('resize', function() { 
            updateCoords();
        });
        
        if ($.browser.safari) {
            $(window).bind('scroll', updateCoords);
        }
        
        if ($.browser.safari) {
            setTimeout(function() {  
                    updateKeyboardSizeFunc(true);                  
                    selectionElm.css('display', 'block');
                    updateKeysNumFunc();                    
                }, 100);
        }

        setTimeout(updateCoords, 100);
		                                
	},
	
	getKeysNumberFromSelectionWidth: function(selectionWidth, fullWidth/*, fullWidthMode*/) {
	   return Math.ceil(selectionWidth / (fullWidth / this.TOTAL_SEL_KEYS));
		/* var savedValue = 1;
		for (sizeValue in this.keyboardSizeToKeysNumberMap) {			
			if ((selectionWidth + (fullWidthMode ? (this.LEFT_PADDING_WIDTH + this.BORDER_WIDTH) : 0)) >= 
			                                             parseInt(sizeValue)) {
				savedValue = this.keyboardSizeToKeysNumberMap[sizeValue];
			} else {
				return savedValue;
			}
		};
		return savedValue; */
   }
	
}

function initTabs() {
    var tabsMap = [
        { pickler: 'synth-tab-pick',
          tabHolder: 'synth-tab'},
        { pickler: 'arrange-tab-pick',
          tabHolder: 'arrange-tab'},
        { pickler: 'digital-tab-pick',
          tabHolder: 'digital-tab'},
        { pickler: 'midi-tab-pick',
          tabHolder: 'midi-tab'}          
    ];
    
    for (tabId in tabsMap) {
        var tabData = tabsMap[tabId];
        $('#' + tabData.pickler).attr('container', tabData.tabHolder); 
    }
    
    $('#tabs-block .tab').hide();
    $('#' + tabsMap[0].tabHolder).show();     
    $('#' + tabsMap[0].pickler).parent().addClass('on');
    $('ul#picks-holder li a').click(function(){ 
        $('ul#picks-holder li').removeClass('on'); 
        $(this).parent().addClass('on');
        $('#tabs-block .tab').hide(); 
        $('#' + $(this).attr('container')).show();
		keyboard.init( $(this).attr('container'));
        return false;
    });    
    
}

$().ready(function() { keyboard.init('synth-tab'); initTabs(); });
