function SKEngineHandler(){
    this.init = function(){

        jQuery('.sk_videoContainer').each(function(indx){
            var videoContainer = jQuery(this);
            var json = videoContainer.find('.jsonDataTA').html();
            videoContainer.find('.jsonDataTA').remove();
            
            var mjson_data = new MainData(); 
            var vContainerModel;       
            if(json==""){
                //implement failback solution        
                return;
            }else{                  
                var temp_data = jQuery.parseJSON(json);
                mjson_data = jQuery.extend(new MainData(), temp_data);
                mjson_data.isEmpty = false;
                vContainerModel = jQuery.extend(new VideoContainerModel(), mjson_data.getVideoContainerModel());
            }            
            
            var videoTemplate = "";
            if(frontend_requirements()){
                videoTemplate = IFrameTemplates.getInstance().getVideoITemplate(vContainerModel.getVideoID(), vContainerModel.getVideoWidth(), vContainerModel.getVideoHeight(), vContainerModel.getIFrameID());
            }else{
                videoTemplate = IFrameTemplates.getInstance().getVideoTemplateFallback(vContainerModel.getVideoID(), vContainerModel.getVideoWidth(), vContainerModel.getVideoHeight(), vContainerModel.getIFrameID());
            }
            jQuery(videoTemplate).appendTo(videoContainer.find('.sk_videoContent'));
            
            if(frontend_requirements() && !isiOS()){
                var vidEngine = new SKVideoEngine();
                vidEngine.init(json, videoContainer);
            }   
        });
    }
}


//SK engine
function SKVideoEngine(){
    this.mjson_data;
    var vContainerModel;
    var player;
    var isPlaying;
    var _self = this;
    var timer;
    this.videoContainerUI;
    this.modelFront;
    this.viewFront; 
    
    var minContainerWidth = 0;
    var minContainerHeight = 0;
    
    var iframeID;    
    
    this.init = function(json, videoContainerJQ){
        this.videoContainerUI = videoContainerJQ;
        this.mjson_data = new MainData();        
        if(json==""){          
            return;
        }
        
        //unpack data
        var temp_data = jQuery.parseJSON(json);
        this.mjson_data = jQuery.extend(new MainData(), temp_data);
        this.mjson_data.isEmpty = false;
        vContainerModel = jQuery.extend(new VideoContainerModel(), this.mjson_data.getVideoContainerModel());                                   
        
        minContainerWidth = vContainerModel.getVideoWidth();
        minContainerHeight = vContainerModel.getVideoHeight(); 
        
        iframeID = IFrameTemplates.ITEMPLATE+vContainerModel.getIFrameID();
        
        //create player
        player = new YT.Player(iframeID, {
            height: '100%',
            width: '100%',
            videoId: vContainerModel.getVideoID(),
            events: {
              'onReady': onPlayerReady,
              'onStateChange': onPlayerStateChange
            }
        });                
    }
    
    var isPlayerReady;
    this.wmodeAdded = false;
    //player is ready
    function onPlayerReady(event){ 
		var state = player.getPlayerState();
        var iframe = _self.videoContainerUI.find('#'+iframeID); 
        if(!_self.wmodeAdded && !vap_isMobile){
            _self.wmodeAdded = true;                       
            iframe.attr('src', iframe.attr('src')+'&amp;wmode=transparent&rel=0');          
            return;
        }
        extractData();
        isPlayerReady = true;
        EventBus.addEventListener(Event.SK_WINDOW_RESIZE, windowResizeHandler);

        iframe.css('width', '100%');
		engine_start();
    }
    
    //window resize handler
    function windowResizeHandler(e){
        if(parseFloat(minContainerWidth)>_self.videoContainerUI.width()){
            //smaller container
            _self.viewFront.setRestrictBasedOnSize(true);
        }else{
            _self.viewFront.setRestrictBasedOnSize(false);
        }
    }
    
    var isPlayerError;
    //player error
    function onPlayerError(e){
        isPlayerError = true;
    }
    //playet state change
    function onPlayerStateChange(event){
        if(!isPlayerReady){
            //TBD - inform error
            return;
        }
        if(event.data==1){
            //playing
            engine_start();
        }else{
            //not playing
            engine_stop();
        }   
    }
    

    //data ready
    function extractData(){

        if(_self.mjson_data.getAssets()!=undefined){            
            var data = jQuery.extend(new Array(), _self.mjson_data.getAssets());
            _self.modelFront = new VideoAssetsModelFront();
            _self.viewFront = new VideoAssetsViewFront(_self.videoContainerUI, _self.modelFront);
            _self.modelFront.init();
            _self.modelFront.setData(data);
            _self.viewFront.setPlayer(player);           
        }else{
            //undefined data
            //alert('Alert! Create an ad first!');
        }          
    }
    
    //start
    function engine_start(){
        timer = setInterval(run_thread, 200);
    }
    //stop
    function engine_stop(){
        clearInterval(timer);
    }     
    
    var onTime;
    //running
    function run_thread(){
        if(_self.viewFront!=undefined&&_self.viewFront!=null){
            _self.viewFront.run(parseFloat(player.getCurrentTime()), player.getDuration());
            if(onTime!=undefined && onTime>player.getCurrentTime()){
                //test
            }
        }
    }
    
    
    //gcc
    this.gcc = function(){
        try{
            player.destroy();
            engine_stop();
        }catch(e){}
    }
        
}





/* VIDEO ASSETS view front
================================================== */
function VideoAssetsViewFront(dom_el, model){
    
    var holdAssetsUI = new Array();
            
    //init view
    this.init(dom_el, model);
    var _this = this;
    
    model.addAssetToView = function(genericAsset){
        _this.onAssetAdded({data: genericAsset});
    }    
    
    this._player;
    this.setPlayer = function(val){
        this._player = val;
    }
            
    //run 
    this.run = function(current_time, vid_duration){
        if(isClosed || _this.restrictBasedOnSize){
            return;
        }        
        for(var i=0;i<holdAssetsUI.length;i++){
            var m = holdAssetsUI[i].getModel();            
            var showedUp = m.getHasShowed();
            var hasLeaved = m.getHasLeaved();         
            
            var ui = holdAssetsUI[i].getEl();
            var showTimeStart = m.getIncomeStartAt();
            var showTimeDuration = m.getIncomingAnimationTime();            
            var endAt = m.getOutgoingStartAt();
            var endDuration = m.getOutgoingAnimationTime();            
            
            var type = m.getType();
            var endTime = showTimeDuration + showTimeStart;                     
            if(endTime < current_time){
						ui.css('display', 'none');
						 m.setHasShowed(false);
						m.setHasLeaved(true);
						switch(outAnimationType)
                    {                                
                        case 'none':
                          ui.css('display', 'none');
                          break;
                        case 'popout':
                          TweenLite.to(ui, endDuration, {css:{opacity:0, scale: 0}, ease:outEfx});
                          break;
                        case 'fadeout':
                          TweenLite.to(ui, endDuration, {css:{opacity:0}, ease:outEfx});
                          break;
                        case 'left':
                          TweenLite.to(ui, endDuration, {css:{left:-ui.width()}, ease:outEfx});
                          break;
                        case 'leftfade':
                          TweenLite.to(ui, endDuration, {css:{left:-ui.width(), opacity: 0}, ease:outEfx});
                          break;                          
                        case 'right':
                          TweenLite.to(ui, endDuration, {css:{left:_this.getEl().width()}, ease:outEfx});
                          break;
                        case 'rightfade':
                          TweenLite.to(ui, endDuration, {css:{left:_this.getEl().width(), opacity: 0}, ease:outEfx});
                          break;                          
                        case 'top':
                          TweenLite.to(ui, endDuration, {css:{top:-ui.height()}, ease:outEfx});
                          break;
                        case 'topfade':
                          TweenLite.to(ui, endDuration, {css:{top:-ui.height(), opacity: 0}, ease:outEfx});
                          break;                          
                        case 'bottom':
                          TweenLite.to(ui, endDuration, {css:{top:_this.getEl().height()}, ease:outEfx});
                          break;
                        case 'bottomfade':
                          TweenLite.to(ui, endDuration, {css:{top:_this.getEl().height(), opacity: 0}, ease:outEfx});
                          break;                                                                                                                                                                                     
                    }						
					}
            //show first time
            if(!showedUp&&!hasLeaved){ 
			
                var showAnimationType = m.getIncomingAnimationType();
                var showEfx = m.getIncomingAnimationEfx(); 
                                              
                var opacityM = 1;
                if(type==GenericAssetModel.RECTANGLE){
                   opacityM = m.getOpacity();
                }
                                                
                if((showTimeStart<current_time) && (showTimeStart<current_time+.3)){
                    m.setHasShowed(true);
                    if(m.getStopVideoOnShow()){
                       try{
                          _this._player.pauseVideo();
                       }catch(e){}
                    }       
                    
                    switch(showAnimationType)
                    {
					
                        case 'none':
                          ui.css('display', 'block');
						  
                          break;
                        case 'popin':
                          TweenLite.to(ui, 0, {css:{opacity:0, scale: .1}});                          
                          ui.css('display', 'block');
                          TweenLite.to(ui, showTimeDuration, {css:{opacity:opacityM, scale: 1}, ease:showEfx});
                          break;
                        case 'fadein':
                          TweenLite.to(ui, 0, {css:{opacity:0}});                          
                          ui.css('display', 'block');
                          TweenLite.to(ui, showTimeDuration, {css:{opacity:opacityM}, ease:showEfx});
                          break;
                        case 'left':
                          ui.css('left', -ui.width()+'px');                          
                          ui.css('display', 'block');
                          TweenLite.to(ui, showTimeDuration, {css:{left:parseFloat(m.getPX())}, ease:showEfx});
                          break;
                        case 'right':
                          ui.css('left', _this.getEl().width()+'px');                          
                          ui.css('display', 'block');
                          TweenLite.to(ui, showTimeDuration, {css:{left:parseFloat(m.getPX())}, ease:showEfx});
                          break;
                        case 'top':
                          ui.css('top', -ui.height()+'px');                          
                          ui.css('display', 'block');
                          TweenLite.to(ui, showTimeDuration, {css:{top:parseFloat(m.getPY())}, ease:showEfx});
                          break;
                        case 'bottom':
                          ui.css('top', _this.getEl().height()+'px');                          
                          ui.css('display', 'block');
                          TweenLite.to(ui, showTimeDuration, {css:{top:parseFloat(m.getPY())}, ease:showEfx});
                          break;                                                                                                                                                           
                    }
					
                }
					
				
            }//end showed up
            
            var isExitAnimation = m.getIsOutgoing();
            
            if(!hasLeaved&&showedUp&&isExitAnimation){
			
                var outAnimationType = m.getOutgoingAnimationType();
                var outEfx = m.getOutgoingAnimationEfx(); 
                                
                                                
                if(endAt<current_time){
                    m.setHasLeaved(true);                
                    if(current_time-.3>endAt){                        
                        ui.css('display', 'none');
                        return;
                    }                      
                    switch(outAnimationType)
                    {                                
                        case 'none':
                          ui.css('display', 'none');
                          break;
                        case 'popout':
                          TweenLite.to(ui, endDuration, {css:{opacity:0, scale: 0}, ease:outEfx});
                          break;
                        case 'fadeout':
                          TweenLite.to(ui, endDuration, {css:{opacity:0}, ease:outEfx});
                          break;
                        case 'left':
                          TweenLite.to(ui, endDuration, {css:{left:-ui.width()}, ease:outEfx});
                          break;
                        case 'leftfade':
                          TweenLite.to(ui, endDuration, {css:{left:-ui.width(), opacity: 0}, ease:outEfx});
                          break;                          
                        case 'right':
                          TweenLite.to(ui, endDuration, {css:{left:_this.getEl().width()}, ease:outEfx});
                          break;
                        case 'rightfade':
                          TweenLite.to(ui, endDuration, {css:{left:_this.getEl().width(), opacity: 0}, ease:outEfx});
                          break;                          
                        case 'top':
                          TweenLite.to(ui, endDuration, {css:{top:-ui.height()}, ease:outEfx});
                          break;
                        case 'topfade':
                          TweenLite.to(ui, endDuration, {css:{top:-ui.height(), opacity: 0}, ease:outEfx});
                          break;                          
                        case 'bottom':
                          TweenLite.to(ui, endDuration, {css:{top:_this.getEl().height()}, ease:outEfx});
                          break;
                        case 'bottomfade':
                          TweenLite.to(ui, endDuration, {css:{top:_this.getEl().height(), opacity: 0}, ease:outEfx});
                          break;                                                                                                                                                                                     
                    }
                }                
            }
            
        }
    } 
    
    this.restrictBasedOnSize;
    //restrict 
    this.setRestrictBasedOnSize = function(val){
        this.restrictBasedOnSize = val;
        if(isClosed){
            return;
        }
        for(var i=0;i<holdAssetsUI.length;i++){
            var assetView = holdAssetsUI[i];
            var ui = holdAssetsUI[i].getEl();
            if(val){
                ui.css('visibility', 'hidden');
            }else{
                ui.css('visibility', 'visible');
            }            
        }
    }
    
    var isClosed;
    //close all ads
    this.closeAllAds = function(){
        isClosed = true;
        for(var i=0;i<holdAssetsUI.length;i++){
            var m = holdAssetsUI[i].getModel(); 
            m.setHasShowed(false);
            var ui = holdAssetsUI[i].getEl();
            m.setHasShowed(false);
            ui.css('display', 'none');            
        }
    }
    
    
    //add assets to stage
    function addAsset(assetView){
        holdAssetsUI.push(assetView);
        assetView.el.css('display', 'none');  
        assetView.el.appendTo(_this.el);                   
        assetView.render();
        var model = assetView.getModel();
        //check for click/target
        if(model.getURL()!=""){
            assetView.el.css('cursor', 'pointer');
            assetView.el.click(function(e){
                e.preventDefault();
                try{
                    window.open(model.getURL(),model.getTarget());                    
                }catch(e){}
            });            
        }        
        
        var type = model.getType();
        //additional actions
        if(type==GenericAssetModel.IMAGE || type==GenericAssetModel.BUTTON){
            if(model.getPlayVidOnClick()){
                assetView.el.click(function(e){
                    e.preventDefault();
                    try{
                        _this._player.playVideo();
                    }catch(e){}
                });
            }            
            if(model.getCloseAdvertise()){
                assetView.el.click(function(e){
                    e.preventDefault();
                    try{
                        _this.closeAllAds();
                    }catch(e){}
                });
            }            
        }
        //additional actions            
    }
    

    
    //asset added listener
    this.onAssetAdded = function(event){        
        var genericAsset;
        var assetModel = event.data;
        switch(assetModel.getType())
        {
            case GenericAssetModel.IMAGE:
              //image
              var img = jQuery('<img class="assetItem" src="'+assetModel.getImage()+'" alt=""/>');
              genericAsset = new ImageAssetView(img, assetModel);
              addAsset(genericAsset);
              break;
            case GenericAssetModel.TEXT:
              //text
              var txt = jQuery('<p class="assetItem"></p>');
              genericAsset = new TextAssetView(txt, assetModel);
              addAsset(genericAsset);              
              break;
            case GenericAssetModel.BUTTON:
              //button
              var btn = jQuery('<a class="assetItem genericButton orange"></a>');
              genericAsset = new ButtonAssetView(btn, assetModel);
              addAsset(genericAsset);              
              break;
            case GenericAssetModel.RECTANGLE:
              //rectangle
              var r = jQuery('<div class="assetItem"></div>');
              genericAsset = new RectangleAssetView(r, assetModel);
              addAsset(genericAsset);              
              break;              
            case GenericAssetModel.CODE:
              //code
              var code = jQuery('<div class="assetItem codeAsset"></div>');
              genericAsset = new CodeAssetView(code, assetModel);
              addAsset(genericAsset);               
              break;
			case GenericAssetModel.FORM:
              //code
			  
              var form = jQuery('<form id="vap_form" action="yes.php" method="post"><div class="text_enter_info">Enter your info</div><input style="background-color:  type="text" name="vap_name" id="vap_name" placeholder="Name"> <br><br> <input type="email" name="vap_email"  id="vap_email" placeholder="Email"> <br><br> <input type="submit" id="vap_submit" value="Submit"> </form>');
              genericAsset = new FormAssetView(form, assetModel);
              addAsset(genericAsset);               
              break;
          }                          
    }
    EventBus.addEventListener(Event.ASSET_ADDED_FRONT, this.onAssetAdded);
        
}
VideoAssetsViewFront.prototype = new GenericView();




/* VIDEO ASSETS model presentation
================================================== */
function VideoAssetsModelFront(){
    var _this = this;
    
    this.init = function(){
        this.data = new Array();
    }    
    this.data;
    
    //set data one time on load
    this.setData = function(val){
        for(var i=0;i<val.length;i++){
            var obj = val[i];
            obj.isSelected = false;
            switch(obj.type)
            {
                case GenericAssetModel.IMAGE:
                  //image
                  obj = jQuery.extend(new ImageAssetModel(), obj);                                    
                  _this.add(obj);
                  break;
                case GenericAssetModel.TEXT:
                  //text
                  obj = jQuery.extend(new TextAssetModel(), obj);                  
                  _this.add(obj);                  
                  break;
                case GenericAssetModel.BUTTON:
                  //button
                  obj = jQuery.extend(new ButtonAssetModel(), obj);                  
                  _this.add(obj);                  
                  break;
                case GenericAssetModel.RECTANGLE:
                  //rectangle
                  obj = jQuery.extend(new RectangleAssetModel(), obj);                  
                  _this.add(obj);                  
                  break;  
				case GenericAssetModel.FORM:
                  //form
                  obj = jQuery.extend(new FormAssetModel(), obj);                  
                  _this.add(obj);                  
                  break;                  
                case GenericAssetModel.CODE:
                  //code
                  obj = jQuery.extend(new CodeAssetModel(), obj);                  
                  _this.add(obj);                  
                  break;
              }             
        }
        //this.data = val;
    }
    this.getData = function(){
        return this.data;
    }    
    
    //add object
    this.add = function(genericAsset){
        genericAsset.setHasShowed(false);
        genericAsset.setHasDepleted(false);
        genericAsset.setIsFrontView(true);                
        _this.data.push(genericAsset);    
        //EventBus.dispatchEvent(new Event(Event.ASSET_ADDED_FRONT, genericAsset));
        _this.addAssetToView(genericAsset);    
    }
    
    this.addAssetToView = function(genericAsset){
        
    }    
        
}
VideoAssetsModelFront.prototype = new GenericModel();
