// com.tts.initial.html5.quiz.ddtarget.autoform
define([
    "jquery",
    "./target.element.builder",
    "./offset.service",
    "./target.registry",
    "./source.collection"
],
function( jq,
          TargetElementBuilder,
          OffsetService,
          TargetRegistry,
          SourceComponentCollection ) {

	"use strict";

    /**
	 * @constructor
	 */
	return function( context, metadata ) {

		// declare private members
		var self = null,
			parameters = metadata.parameters,

            isStandardPlayer = context.getPlayerName() === "standard",

			target,
			targetId = parameters.get( "target_id", "1"),

            offsetService = new OffsetService(context),
        	sourceComponents = new SourceComponentCollection( context, parameters ),
			targetRegistry = new TargetRegistry( context, metadata );

		function createComponent() {

			self = this;

			setComponentBehaviour();

			target = new TargetElementBuilder( context, metadata ).build();

            var shellElement = jq(context.getElement());
            shellElement.css( getCoreCss() )
                .append( target.getTargetDiv() );

            if (context.stage.isInAuthoringMode()) {
                shellElement.prepend( createAuthoringShield() );
            }
		}

		function setComponentBehaviour(){
			context.page.event.bindOnEnter( self );
			context.page.event.bindOnExit( self );
			context.page.quiz.event.bindOnUserSolution( self );
            context.page.quiz.event.bindOnBestPracticeSolution( self );
		}

        function getCoreCss(){

            var coreStyles = {
                "cursor": "default"
            };

            if( !isStandardPlayer ) {
                coreStyles["width"] = "100%";
                coreStyles["height"] = "100%";
            }

            return coreStyles;
		}

		function createAuthoringShield() {
			return jq( document.createElement("div") )
				.css({
					"width" : "100%",
					"height" : "100%",
					"position" : "absolute",
					"opacity" : "0.15",
					"background-image" : parameters.get("background-transparency", "0" ) === 100 ? "url(\"" + context.getPath() + "invis.png\")" : ""
				});
		}

		function initialize() {

			if( isStandardPlayer ) {
				sourceComponents.removeAll();
			}

			targetRegistry.register( self );
		}

		function cleanUp() {
			targetRegistry.deregister( self );
		}

		function onSourceDrop( sourceObject ) {

			if( !sourceComponents.isCapacityAvailable() ) {
				return false;
			}

            sourceComponents.addByUser( sourceObject );
            target.setDefaultStyle();

			return true;
		}

        function setAsUserSolution( sourceObject ) {
            sourceComponents.addForSolution( sourceObject );
        }

		function initializeUserSolution() {
            sourceComponents.removeAll();
		}

		function setAsBestPracticeSolution( sourceObject ) {

			if( !sourceComponents.isCapacityAvailable() ) {
				return false;
			}

            sourceComponents.addForSolution( sourceObject );
			return true;
		}

		function initializeBestPracticeSolution(){
            sourceComponents.removeAll();
		}

		// revealing public API
		return {

			onLoading : createComponent,
			onEnterPage : initialize,
			onExitPage : cleanUp,
			getId : function() {
				return metadata.getId();
			},
			getTargetId : function() {
				return targetId;
			},
            getPosition : function(){
				var shellElement = jq(context.getElement());
				return {
					offset : offsetService.getGlobalOffset( context.getPositioningElement() ),
					size : {
						width : shellElement.width(),
                        height : shellElement.height()
					}
				};
			},
			onDragStart : function( sourceComponent ) {
                sourceComponents.remove( sourceComponent );
			},
			onDragOver : function() {
                target.setDragOverTargetStyle();
			},
			onDragOut : function() {
                target.setDefaultStyle();
			},
			onDrop : onSourceDrop,
			onUserSolution : initializeUserSolution,
            setAsUserSolution : setAsUserSolution,
            onBestPracticeSolution : initializeBestPracticeSolution,
			setAsBestPracticeSolution : setAsBestPracticeSolution
		};
	};
});
