// com.tts.initial.html5.quiz.ddsource.autoform
define( ["jquery"], function( jq ) {

    "use strict";

    function OffsetService( context ){

        /*
         Gets global offset for elements with absolute positioning.
         The offset includes stage offset and ignores css zoom factor.
        */
        function getGlobalOffset( element ){

            var offset = getCssOffset( element ),
                groupOffset = getGroupOffset( element );

            if( groupOffset.left !== 0 || groupOffset.top !== 0 ){
                return addGroupOffset( element, offset, groupOffset );
            }

            return offset;
        }

        function getCssOffset( element ){

            var offset = {
                "left" : parseInt( jq(element).css( "left" ).replace("px",""), 10) || 0,
                "top": parseInt( jq(element).css( "top" ).replace("px",""), 10) || 0
            };

            return offset;
        }

        function addGroupOffset( element, offset, groupOffset ){
            return {
                left : offset.left + groupOffset.left,
                top : offset.top + groupOffset.top
                };
        }

        /*
         Sets the global offset for elements and change position handling to absolute.
         The offset should include stage offset and ignores css zoom factor.
        */
        function setGlobalOffset( element, offset ){

            var groupOffset = getGroupOffset( element );

            if( groupOffset.left !== 0 || groupOffset.top !== 0 ){
                var targetOffset = removeGroupOffset( element, offset, groupOffset );
                jq(element).css({
                    "left": targetOffset.left + "px",
                    "top": targetOffset.top + "px"
                });
                return;
            }

            jq(element).css({
                "position": "absolute",
                "left": offset.left + "px",
                "top": offset.top + "px"
            });
        }

        function removeGroupOffset( element, offset, groupOffset ){
            return {
                left : offset.left - groupOffset.left,
                top : offset.top - groupOffset.top
            };
        }

        /*
         * This method based on the convention that no absolute element is placed in the chain of tts group elements
         * and all css positions set as px units
         */
        function getGroupOffset( element ) {

            var groupOffset = {
                    left: 0,
                    top: 0
                },
                jqElement = jq(element),
                parents = jqElement.parents(),
                parent,
                position;

            parents.each( function( index, element ){
                parent = jq(element);
                if( parent.hasClass("Group") || parent.hasClass("ttclassgroup") ){
                    position = getCssOffset( parent ); //parent.position();
                    groupOffset.left += position.left;
                    groupOffset.top += position.top;
                }
            });

            return groupOffset;
        }

        function getPointerPosition( event ){

            var translateEventPosition = function( eventPos ) {
                return {
                    left: eventPos.pageX,
                    top: eventPos.pageY
                };
            };

            if( event.originalEvent ) {

                if( event.originalEvent.touches && event.originalEvent.touches[0] ){
                    return translateEventPosition(event.originalEvent.touches[0]);
                }

                if( event.originalEvent.changedTouches && event.originalEvent.changedTouches[0] ){
                    return translateEventPosition(event.originalEvent.changedTouches[0]);
                }
            }

            return translateEventPosition(event);
        }

        function removeStageModifier( position ) {

            var stageZoom = context.stage.getZoom(),
                stageOffset = context.stage.getOffset();

            return {
                left: (position.left - stageOffset.left) / stageZoom,
                top: (position.top - stageOffset.top) / stageZoom
                }
            }

        function roundPos( position ){
            return {
                left: Math.round(position.left),
                top:  Math.round(position.top)
            };

        }

        return {
            getGlobalOffset: getGlobalOffset,
            setGlobalOffset: setGlobalOffset,
            removeGroupOffset : function( element, offset ){
                var groupOffset = getGroupOffset( element );
                if( groupOffset.left !== 0 || groupOffset.top !== 0 ){
                    return removeGroupOffset( element, offset, groupOffset);
                }
                return offset;
            },
            getPointerPositionFromEvent : function( event ){
                var pos = getPointerPosition( event );
                pos = removeStageModifier( pos );
                return roundPos( pos );
            }
        }
    }

    return OffsetService;
});
