    var GMapKitMapControls3d = function(){
        this.sliderStep = 9;
        this.imgSrc = "http://maps.google.com/intl/en_ALL/mapfiles/mapcontrols3d.png";
    };
    
    GMapKitMapControls3d.prototype = new GControl();
    GMapKitMapControls3d.prototype._map = null;
    GMapKitMapControls3d.prototype._container = null;
    GMapKitMapControls3d.prototype._slider = null;
    
    GMapKitMapControls3d.prototype.initialize = function(map) {
        GMapKitMapControls3d.prototype._map = map;
        new GKeyboardHandler(map);
        
        var agt = navigator.userAgent.toLowerCase();
        var isIE = 0;
        var _handleList = new Array();
        if(agt.indexOf('msie') != -1 ){isIE = 1;};
        
        
        //common image
        var commonImg = new Image();
        commonImg.src=this.imgSrc;
        
        //===========================================//
        //       calculation of controller size      //
        //===========================================//
        var currentMapType=map.getCurrentMapType();
        var minZoom = parseInt(currentMapType.getMinimumResolution());
        var maxZoom =0;
        var maptypes = map.getMapTypes();
        for(var i=0;i<maptypes.length;i++){
            if(maptypes[i].getMaximumResolution()>maxZoom){maxZoom=maptypes[i].getMaximumResolution();};
        };
        
        GMapKitMapControls3d.prototype._maxZoom = parseInt(maxZoom);
        GMapKitMapControls3d.prototype._step = this.sliderStep;
        var ctrlHeight = (86+5) + (maxZoom-minZoom +1)* this.sliderStep + 5;

        //===========================================//
        //             create container              //
        //===========================================//
        var container=document.createElement("div");
        with(container.style){
            width="59px";
            height=(ctrlHeight+this.sliderStep+2)+"px";
            overflow="hidden";
            padding="0";
            MozUserSelect="none";
            textAlign="left";
        };
         _handleList["container"] = container;
         GMapKitMapControls3d.prototype._container = container;
        
        //===========================================//
        //        make position control area         //
        //===========================================//
        
        //image load
        var imgContainer = document.createElement("div");
        with(imgContainer.style){
            width="59px";
            height="62px";
            overflow="hidden";
            if(isIE){
                filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this.imgSrc+"')";
            };
        };
        container.appendChild(imgContainer); 
        
        if(!isIE){
             var baseImg = commonImg.cloneNode(false);
             with(baseImg.style){
                 position="absolute";
                 left="0px";
                 top="0px";
                 width="59px";
                 height="458px";
             };
             imgContainer.appendChild(baseImg);
        };
        
        //top arrow button
        var topBtn = document.createElement("div");
        with(topBtn.style){
            position="absolute";
            left="20px";
            top="0px";
            width="18px";
            height="18px";
            cursor="pointer";
            overflow="hidden";
        };
        topBtn.title="up";
        container.appendChild(topBtn); 
        
        
        //left arrow button
        var leftBtn = topBtn.cloneNode(true);
        with(leftBtn.style){
            left="0px";
            top="20px";
        };
        leftBtn.title="left";
        container.appendChild(leftBtn); 
        
        
        //right arrow button
        var rightBtn = topBtn.cloneNode(true);
        with(rightBtn.style){
            left="40px";
            top="20px";
        };
        rightBtn.title="right";
        container.appendChild(rightBtn); 
        
        //bottom arrow button
        var bottomBtn = topBtn.cloneNode(true);
        with(bottomBtn.style){
            left="20px";
            top="40px";
        };
        bottomBtn.title="bottom";
        container.appendChild(bottomBtn); 
        
        //center button
        var homeBtn = topBtn.cloneNode(true);
        with(homeBtn.style){
            left="20px";
            top="20px";
        };
        homeBtn.title="home position";
        container.appendChild(homeBtn); 
        
        
        _handleList["topBtn"] = topBtn;
        _handleList["leftBtn"] = leftBtn;
        _handleList["rightBtn"] = rightBtn;
        _handleList["bottomBtn"] = bottomBtn;
        _handleList["homeBtn"] = homeBtn;

        //===========================================//
        //            zoom slider Button             //
        //===========================================//
        
        var zoomSlideBarContainer = document.createElement("div");
        with(zoomSlideBarContainer.style){
            position ="absolute";
            left="19px";
            top="86px";
            width="22px";
            height=((maxZoom-minZoom+1)* this.sliderStep) +"px";
            overflow="hidden";
            cursor="pointer";
        };
        container.appendChild(zoomSlideBarContainer); 
        _handleList["slideBar"] = zoomSlideBarContainer;

        var zoomLevel = map.getZoom();
        //zoomOut Btn load
        var zoomSliderContainer = document.createElement("div");
        with(zoomSliderContainer.style){
            position ="absolute";
            left=0;
            top=((maxZoom - zoomLevel)* this.sliderStep+1)+"px";
            width="22px";
            height="14px";
            overflow="hidden";
            cursor="url(http://maps.google.com/intl/en_ALL/mapfiles/openhand.cur), default";
        };
        zoomSlideBarContainer.appendChild(zoomSliderContainer); 
        _handleList["slideBarContainer"] = zoomSliderContainer;
        
        if(isIE){
            var zoomSliderBtnImg = document.createElement("div");
            with(zoomSliderBtnImg.style){
                position ="relative";
                left=0;
                top="-384px";
                width="22px";
                height="14px";
                overflow="hidden";
                filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this.imgSrc+"')";
            };
            zoomSliderContainer.appendChild(zoomSliderBtnImg);
            _handleList["zoomSlider"] = zoomSliderBtnImg;
        }else{
            var slideImg = commonImg.cloneNode(false);
            with(slideImg.style){
                position="absolute";
                left="0px";
                top="-384px";
                MozUserSelect="none";
                border="0px none";
                margin="0px";
                padding="0px";
                width="59px";
                height="458px";
            };
            zoomSliderContainer.appendChild(slideImg);
            _handleList["zoomSlider"] = slideImg;
        };
        
        //===========================================//
        //              zoom out Button              //
        //===========================================//
        //zoomOut Btn load
        var zoomOutBtnContainer = document.createElement("div");
        with(zoomOutBtnContainer.style){
            position ="absolute";
            left=0;
            top=(86 + (maxZoom - minZoom+1)* this.sliderStep )+"px";
            width="59px";
            height="23px";
            overflow="hidden";
        };
        container.appendChild(zoomOutBtnContainer); 
        
        
        if(isIE){
            var zoomOutBtnImg = document.createElement("div");
            with(zoomOutBtnImg.style){
                position ="relative";
                left=0;
                top="-360px";
                width="59px";
                height="23px";
                overflow="hidden";
                filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this.imgSrc+"')";
            };
            zoomOutBtnContainer.appendChild(zoomOutBtnImg);
        }else{
             var btnImg = commonImg.cloneNode(false);
             with(btnImg.style){
                 position="absolute";
                 left="0px";
                 top="-360px";
                 width="59px";
                 height="458px";
             };
             zoomOutBtnContainer.appendChild(btnImg);
        };
        
        //zoomOut button
        var zoomOutBtn = document.createElement("div");
        with(zoomOutBtn.style){
            position="absolute";
            left="20px";
            top=(91 + (maxZoom-minZoom+1)* this.sliderStep)+"px";
            width="18px";
            height="23px";
            cursor="pointer";
            overflow="hidden";
        };
        zoomOutBtn.title="zoom out";
        container.appendChild(zoomOutBtn); 
        _handleList["zoomOutBtn"] = zoomOutBtn;
        
        //===========================================//
        //              zoom in Button               //
        //===========================================//
        //zoomIn button
        var zoomInBtn = document.createElement("div");
        with(zoomInBtn.style){
            position="absolute";
            left="20px";
            top="65px";
            width="18px";
            height="23px";
            cursor="pointer";
            overflow="hidden";
        };
        zoomInBtn.title="zoom in";
        container.appendChild(zoomInBtn); 
        _handleList["zoomInBtn"] = zoomInBtn;

        
        //===========================================//
        //                  events                   //
        //===========================================//
        GEvent.addDomListener(_handleList["topBtn"], "click", this._eventTop);
        GEvent.addDomListener(_handleList["leftBtn"], "click", this._eventLeft);
        GEvent.addDomListener(_handleList["rightBtn"], "click", this._eventRight);
        GEvent.addDomListener(_handleList["bottomBtn"], "click", this._eventBottom);
        GEvent.addDomListener(_handleList["homeBtn"], "click", this._eventHome);
        GEvent.addDomListener(_handleList["zoomOutBtn"], "click", this._eventZoomOut);
        GEvent.addDomListener(_handleList["zoomInBtn"], "click", this._eventZoomIn);
        GEvent.addDomListener(_handleList["slideBar"], "click", this._eventSlideBar);
        GEvent.addListener(map, "zoomend", this._eventZoomEnd);
        
        var drgOpt = {
                         container : _handleList["slideBar"]
                     };
        var drgCtrl = new GDraggableObject(_handleList["slideBarContainer"], drgOpt);
        GEvent.addDomListener(drgCtrl, "dragend", this._eventSlideDragEnd);
        GMapKitMapControls3d.prototype._slider =  drgCtrl;
        
        //set current slider position
        this._eventZoomEnd(map.getZoom(), map.getZoom());
        
        map.getContainer().appendChild(container);
        return container;
    };

    GMapKitMapControls3d.prototype._eventTop = function() {
        GMapKitMapControls3d.prototype._map.panDirection(0,1);
    };

    GMapKitMapControls3d.prototype._eventLeft = function() {
        GMapKitMapControls3d.prototype._map.panDirection(1,0);
    };

    GMapKitMapControls3d.prototype._eventRight = function() {
        GMapKitMapControls3d.prototype._map.panDirection(-1,0);
    };

    GMapKitMapControls3d.prototype._eventBottom = function() {
        GMapKitMapControls3d.prototype._map.panDirection(0,-1);
    };

    GMapKitMapControls3d.prototype._eventZoomOut = function() {
        GMapKitMapControls3d.prototype._map.zoomOut();
    };

    GMapKitMapControls3d.prototype._eventZoomIn = function() {
        GMapKitMapControls3d.prototype._map.zoomIn();
    };
    

    GMapKitMapControls3d.prototype._eventSlideBar = function(e) {
        var map=GMapKitMapControls3d.prototype._map;
        //calculate of zoomlevel
        var mouseY = e.clientY;
        var slideStep = GMapKitMapControls3d.prototype._step;
        var maxZoom = GMapKitMapControls3d.prototype._maxZoom;
        var container = GMapKitMapControls3d.prototype._container;
        
        
        //set new zoomLevel
        var ctrlPos = GMapKitMapControls3d.prototype._getDomPosition(container);
        mouseY -= (ctrlPos.y+91);
        var zoomLevel = Math.floor(maxZoom-((mouseY)/slideStep));
        zoomLevel = zoomLevel <0 ? 0 : zoomLevel;
        map.setZoom(zoomLevel);
    };
    
    GMapKitMapControls3d.prototype._getDomPosition = function(that) {
        var agt = navigator.userAgent.toLowerCase();
        var is_ie    = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1));
        var is_gecko = (agt.indexOf('gecko') != -1);
        var is_opera = (agt.indexOf("opera") != -1);
        var targetEle = that;
        var pos = new function(){ this.x = 0; this.y = 0; };
        while( targetEle ){
            pos.x += targetEle.offsetLeft; 
            pos.y += targetEle.offsetTop; 
            targetEle = targetEle.offsetParent;

            if ((targetEle) && (is_ie)) {
                pos.x += (parseInt(GMapKitMapControls3d.prototype.getElementStyle(targetEle,"borderLeftWidth","border-left-width")) || 0);
                pos.y += (parseInt(GMapKitMapControls3d.prototype.getElementStyle(targetEle,"borderTopWidth","border-top-width")) || 0);
            };
        };

        if (is_gecko) {
            var bd = document.getElementsByTagName("BODY")[0];
            pos.x += 2*(parseInt(GMapKitMapControls3d.prototype.getElementStyle(bd,"borderLeftWidth","border-left-width")) || 0);
            pos.y += 2*(parseInt(GMapKitMapControls3d.prototype.getElementStyle(bd,"borderTopWidth","border-top-width")) || 0);
        };
        return pos;
    };

    GMapKitMapControls3d.prototype.getElementStyle=function(targetElm,IEStyleProp,CSSStyleProp) {
        var elem = targetElm;
        if (elem.currentStyle) {
            return elem.currentStyle[IEStyleProp];
        }else if (window.getComputedStyle) {
            var compStyle = window.getComputedStyle(elem,"");
            return compStyle.getPropertyValue(CSSStyleProp);
        };
    };
    
    GMapKitMapControls3d.prototype.stopDefaultAndPropagation=function(e){
        if(e.stopPropagation){
            e.stopPropagation();
        };
        if(window.event){
            window.event.cancelBubble=true;
        };
        if(e.preventDefault){
            e.preventDefault();
        };
        if(window.event){
            window.event.returnValue = false;
        };
    };

    GMapKitMapControls3d.prototype._eventSlideDragEnd = function(e) {
        //calculate of zoomlevel
        var maxZoom = GMapKitMapControls3d.prototype._maxZoom;
        var mouseY = GMapKitMapControls3d.prototype._slider.top;
        var step = GMapKitMapControls3d.prototype._step;
        
        //set new zoomLevel
        var zoomLevel = Math.floor(maxZoom-(mouseY/step));
        zoomLevel = zoomLevel <0 ? 0 : zoomLevel;
        GMapKitMapControls3d.prototype._map.setZoom(zoomLevel);
    };
    
    GMapKitMapControls3d.prototype._eventHome = function() {
        GMapKitMapControls3d.prototype._map.returnToSavedPosition();
    };
    
    GMapKitMapControls3d.prototype._eventZoomEnd = function(oldZoom, newZoom) {
        var maxZoom = GMapKitMapControls3d.prototype._maxZoom;
        var step = GMapKitMapControls3d.prototype._step;
        GMapKitMapControls3d.prototype._slider.moveTo(new GPoint(0, (maxZoom - newZoom)* step));
    };
    
    GMapKitMapControls3d.prototype.getDefaultPosition = function() {
        return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(10, 10));
    };
    
    GMapKitMapControls3d.prototype.selectable = function(){
        return false;
    };
    
    GMapKitMapControls3d.prototype.printable = function(){
        return true;
    };
