﻿//Copyright Set-Soft A.Ş.
//http://www.set-soft.com 

///<reference path="Type.js" />


TYPE.registerNamespace('Web.Input');

Web.Input.SpecialKeys=
{
    Back:8,
    Enter:13,
    LeftArrow:37,
    TopArrow:38,
    RightArrow:39,
    DownArrow:40,
    SpaceBar:32,
    CTRL:17,
    Shift:16,
    Alt:18,
    Tab:9,
    BiggerSmaller:226
}

Web.Input.KeyRegistrationType=
{
    Combination:1,
    KeyUp:2
}

Web.Input.KeyboardRegistrationInfo=function(type,keyCombination,targetObjectInstance,targetFunc,preventDefaultAction,tag)
{
    var me=this;
    this.type = type;
    this.charCodes=new Array();
    this.keyCombination=keyCombination;
    this.targetObject=targetObjectInstance;
    this.targetFunction=targetFunc;
    this.preventDefault=preventDefaultAction;
    this.tagObj=tag;
    
    this.ctrl=false;
    this.shift=false;
    this.alt=false;
    
    this.init=function()
    {
        var parts=me.keyCombination.split('+');
        for(var i=0;i<parts.length;i++)
        {
            new String()
            var code;
            if(parts[i].length>1)
            {
                var p = parts[i];
                if(p.toUpperCase() == "CTRL" && me.ctrl==false)
                {    
                    me.ctrl=true;
                    code = 17;
                }
                
                if(p.toUpperCase() == "SHIFT" && me.shift==false)
                {
                    me.shift=true;
                    code=16;
                }
                
                if(p.toUpperCase() == "ALT" && me.alt==false)
                {   
                    me.alt=true;            
                    code=18;
                }
            }
            else
            {
                if(parts[i].length==0)continue;
                code = parts[i].toUpperCase().charCodeAt(0);
            }
            
            me.charCodes.push(code);            
        }    
    }
    
    this.equals=function(type,keyCombination,targetObjectInstance,targetFunction)
    {
        return (me.type=type &&
                me.keyCombination == keyCombination &&
                me.targetObject == targetObjectInstance &&
                me.targetFunction == targetFunction);
    }
}

Web.Input.KeyboardManager=function(browserManager)
{
    var me=this;
    this.browserManager= (browserManager == null) ?  new Web.Core.BrowserManager() : browserManager;//hack i düzeltmeyi unutmaa
    this.keyboardEventList=new Web.Collections.List();
    this.lastPressedKeyCodes=new Web.Collections.List();
    
    this.ctrlPressed=false;
    this.shiftPressed=false;
    this.altPressed=false;
    this.currentEvent=null;     
    
    this.addCombinationListener=function(keyCombination,targetObjectInstance,targetFunction,preventDefaultAction,tag)
    {
       var info = new Web.Input.KeyboardRegistrationInfo('keydown',keyCombination,targetObjectInstance,targetFunction,preventDefaultAction,tag);
       info.init();
       
       this.keyboardEventList.add(info);
    }
    
    this.addListenerByKeyCodes=function(type,keys,targetObjectInstance,targetFunction,preventDefault,tag,keycodes)
    {
        var kinfToAdd = new Web.Input.KeyboardRegistrationInfo(type,keys,targetObjectInstance,targetFunction,preventDefault,tag);
        kinfToAdd.init();
        for(var i=6;i<arguments.length;i++)
            kinfToAdd.charCodes.push(arguments[i]);
        
        this.keyboardEventList.add(kinfToAdd);
    }
    
    this.removeCombinationListener=function(type,keyCombination,targetObjectInstance,targetFunction)
    {
        for(var i=0;i<this.keyboardEventList.count;i++)
        {
            if(this.keyboardEventList.getItem(i).equals(type,keyCombination,targetObjectInstance,targetFunction))
            {
                this.keyboardEventList.removeByIndex(i);
                return;
            }
        }    
    }
    
    this.addKeyUpListener=function(key,targetObjectInstance,targetFunction,tag)
    {
        var info = new Web.Input.KeyboardRegistrationInfo('keyup',key,targetObjectInstance,targetFunction,false,tag);
        info.init();
        
        this.keyboardEventList.add(info);
    }
    
    this.processKeyUp=function(e)
    {
        me.setEventProps(e);
        
        var keyCode = (e.which) ? e.which : e.keyCode;
        for(var i=0;i<me.keyboardEventList.count;i++)
        {
            var reg=me.keyboardEventList.getItem(i);
            
            if(reg.type!='keyup')continue;
            
            if(reg.charCodes[0] == keyCode)
                reg.targetFunction.call(reg.targetObject,me,reg.tagObj);
        }
        
        me.clearEventProps();
    }
    
    this.processKeyDown=function(e)
    {
        me.setEventProps(e);
        
        var keyCode = (e.which) ? e.which : e.keyCode;
        if(me.lastPressedKeyCodes.count<4)
        {
            me.lastPressedKeyCodes.add(keyCode);
        }
        else
        {
            me.lastPressedKeyCodes.removeByIndex(0);
            me.lastPressedKeyCodes.add(keyCode);
        }
        
        var preventDef=false;
        
        for(var i=0;i<me.keyboardEventList.count;i++)
        {
            var reg=me.keyboardEventList.getItem(i);
            
            if(reg.type!='keydown')continue;
                        
            if(reg.ctrl && e['ctrlKey'] == false)continue;
            if(reg.shift && e['shiftKey'] == false)continue;
            if(reg.alt && e['altKey'] == false)continue;
            
            var done=true;
            
            for (var p=0,s=me.lastPressedKeyCodes.count - reg.charCodes.length;s<4;s++,p++)
            {
                if(reg.charCodes[p] != me.lastPressedKeyCodes.getItem(s))
                {
                    done=false;
                }
            }
            
            if(done)
            {
                reg.targetFunction.call(reg.targetObject,me,reg.tagObj);
                if(reg.preventDefault)preventDef=true;
            }
        }
        
        if(preventDef)
        {
            try 
            {
                e.keyCode=0;
                e.cancelBubble=true;
                e.returnValue=false;
            }
            catch(ex)
            {
            }
        }
        
        me.clearEventProps();
    }
    
    this.setEventProps=function(evt)
    {
        this.currentEvent=evt;
        this.ctrlPressed=evt['ctrlKey'];
        this.shiftPressed=evt['shiftKey'];
        this.altPressed=evt['altKey'];
    }
    
    this.clearEventProps=function()
    {
        this.currentEvent=null;
        this.ctrlPressed=false;
        this.shiftPressed=false;
        this.altPressed=false;
    }

    this.init=function()
    {
        this.browserManager.attachEvent(document,'onkeydown',this.processKeyDown);
        this.browserManager.attachEvent(document,'onkeyup',this.processKeyUp);
        this.lastPressedKeyCodes.add(-1);
        this.lastPressedKeyCodes.add(-1);
        this.lastPressedKeyCodes.add(-1);
        this.lastPressedKeyCodes.add(-1);
    }
    
    this.addDocumentToTrack=function(doc)
    {
        this.browserManager.attachEvent(doc,'onkeydown',this.processKeyDown);
        this.browserManager.attachEvent(doc,'onkeyup',this.processKeyUp);
    }
    
    this.removeDocumentFromTrack=function(doc)
    {
        this.browserManager.detachEvent(doc,'onkeydown',this.processKeyDown);
        this.browserManager.detachEvent(doc,'onkeyup',this.processKeyUp);
    }
}
