function openProject(id){
  $("#dialog").dialog('close');
  
  currentProject = visuModel.getProjectById(id);
  
  loadProject(currentProject, showProject);
}

function showProject(project){
  for (i in currentProject.getPages()) {
    var pageIndexLink = $(document.createElement("div"));
    pageIndexLink.text(currentProject.getPages()[i].title);
    
    var id = currentProject.getPages()[i].id;
    pageIndexLink.attr({
      id: "pageIndexLink_" + id
    });
    
    pageIndexLink.bind("click", function(event){
      openPage(event.target.id.split("_")[1]);
    });
    
    $("#pageindex").append(pageIndexLink);
  }
  
  showPageIndex = currentProject.showPageIndex;
  showToolBar = currentProject.showToolBar;
  showStatusBar = currentProject.showDisconnectBar;
  
  if (currentProject.kioskMode) {
    window.moveTo(0, 0);
    window.resizeTo(screen.availWidth, screen.availHeight);
  }

  var spi = user_startpage_id == -1 ? currentProject.startId : user_startpage_id;
  
  if(!user_global_page_access && !user_page_access[spi]) {
    spi = currentProject.startId;
    var index = 0;
    while(!user_global_page_access && !user_page_access[spi] && index < currentProject.getPages().length) {
        spi = currentProject.getPages()[index++].id;
    } 
  }

  var page = currentProject.getPageById(spi);
  var index = 0;
  while(page == null || !page.isVisuPage()) {
    page = currentProject.getPages()[index++];
  }

  if (page != null && page.isVisuPage()) {
    openPage(page.id);
  }
  
  VC.setReturnToStartPage(currentProject.returnToStartPageDelay * 60000);
}

var pageHistory = new Array();
var pageHistoryIndex = 0;
function openNextPage() {
  if(pageHistoryIndex < pageHistory.length - 1) {
    openPage(pageHistory[++pageHistoryIndex], true);
  }
}

function openPrevPage() {
  if(pageHistoryIndex > 0) {
    openPage(pageHistory[--pageHistoryIndex], true);
  }
}

function openPage(id, noHistory) {
  if(!user_global_page_access && !user_page_access[id]) {
    alert("you dont have access to this page!");
    return;
  }

  if(!noHistory) {
    pageHistory.splice(pageHistoryIndex + 1, pageHistory.length - pageHistoryIndex);
    pageHistory[pageHistory.length] = id;
    if(pageHistory.length == 11) {
      pageHistory.shift();
    }
    pageHistoryIndex = pageHistory.length - 1;
  }
  var nextPage = currentProject.getPageById(id);
  if(nextPage === null || nextPage === undefined) return;
  
  if (!nextPage.hasBeenLoaded) {
    loadPage(nextPage, function onFinish(){
      if (nextPage.masterId != -1) {
        var nextMaster = currentProject.getPageById(nextPage.masterId);
        if (!nextMaster.hasBeenLoaded) {
          loadPage(nextMaster, function(){
            showPage(nextPage);
          });
        } else {
          showPage(nextPage);
        }
      } else {
        showPage(nextPage);
      }
    });
  } else {
    showPage(nextPage);
  } 
}

function showMaster() {
  if (currentPage.masterId == -1) {
    if(currentMaster != null) {
      knxRefresher.clearCategory("master_page_"+currentMaster.id);
      OC.hideObjects(currentMaster, false);
      currentMaster = null;
    }
    return;
  }
  if(currentMaster != null) {
    if(currentPage.masterId == currentMaster.id) {
      return;
    } else {
      knxRefresher.clearCategory("master_page_"+currentMaster.id);
      OC.hideObjects(currentMaster, false);
    }
  }
  
  currentMaster = currentProject.getPageById(currentPage.masterId);
  
  var knxCategory = "master_page_"+currentMaster.id;
  knxRefresher.setCurrentCategory(knxCategory);
  
  OC.showObjects(currentMaster, $("#page"));
  
  if(currentMaster.cachedObjects) {
    knxRefresher.addCategoryObjects(currentMaster.rObjects);
  } else {
    currentMaster.rObjects = knxRefresher.getCategory(knxCategory);
    currentMaster.cachedObjects = true;
  }
}

var bubbleHandler = null;
function showPage(nextPage){
  if(bubbleHandler == null && $("#page").get(0).addEventListener) {
    bubbleHandler = new BubbleHandler($("#page"), "VisuPage");
    $("#page").get(0).addEventListener("mousedown", bubbleHandler.handleEvent, false);
    $("#page").get(0).addEventListener("mouseup", bubbleHandler.handleEvent, false);
    $("#page").get(0).addEventListener("click", bubbleHandler.handleEvent, false);
    $("#page").get(0).addEventListener("drag", bubbleHandler.handleEvent, false);   
    $("#page").get(0).addEventListener("dragend", bubbleHandler.handleEvent, false);
  }
  if(currentPage != null && nextPage.id == currentPage.id) {
    return;
  }
  if (currentPage != null) {
    knxRefresher.clearCategory("visu_page_"+currentPage.id);
    OC.hideObjects(currentPage, false);
  }
  currentPage = nextPage;
  
  showMaster();
  VC.setPageParameter();
  
  var knxCategory = "visu_page_"+currentPage.id;
  knxRefresher.setCurrentCategory(knxCategory);
  
  OC.showObjects(currentPage, $("#page"));
  
  cacheObjects(knxCategory, currentPage);
  
  if(VC.projectStartPage === null) VC.projectStartPage = currentPage;
  VC.retriggerReturnToStartPage();
}

function cacheObjects(category, target) {
  if(!jQuery.browser.msie && target.cachedObjects) {
    knxRefresher.addCategoryObjects(target.rObjects);
  } else {
    target.rObjects = knxRefresher.getCategory(category);
    target.cachedObjects = true;
  }
  knxRefresher.doRefresh();
}

$.fn.descendantOf = function(element) {
    element = $(element)[0];
    var current = this;
    while (current && current != element && current != document.body) {
        current = $(current).parent()[0];
    }
    if (typeof(current) == "undefined" || typeof(current) == "null") {
        return false;
    } else if (current == element) {
        return true;
    } else if (current == document.body) {
        return false;
    }
};

var BubbleHandler = function (target, id) {
  this.handleEvent = function (event){
    if (event.bubbleHandler)// || event.target === target) 
      return;


    event.bubbleHandler = true;

    //log.info("bubbleHandler: "+ident+" event: "+event.type);

    //cancelBubble(event);
    var objects = $(target).children();
    var obj;
    for (var i = 0; i < objects.length; i++) {
      obj = $(objects[i]);

      if($(event.target).descendantOf(obj)) {
       // log.info("obj.contains target");
        continue;
      }
      
            //log.info("event at "+event.pageX + "_" + event.pageY + " offset: "+event.offsetX + "_"+event.offsetY);
      if (event.pageX >= obj.offset().left &&
          event.pageX <= obj.offset().left + obj.width() &&
          event.pageY >= obj.offset().top &&
          event.pageY <= obj.offset().top + obj.height()) {
      
                //log.info("hit object at: "+obj.offset().left + "_" + obj.offset().top + " " + obj.width() + "x"+obj.height());
        var zIndex;
        try {
            zIndex = $(event.target).css("z-index");
        } catch (e) {
            return;
        }
        if (zIndex === "auto" || zIndex > obj.css("z-index")) {
          //log.info("dispatching event " + event.type +" "+obj.css("z-index"));

          //$("#outerbox").append("dispatching event " + event.type +" "+obj.css("z-index")+ " "+obj.attr("id")+"<br>");
          
          var simulatedEvent = document.createEvent("MouseEvent");
          simulatedEvent.bubbleHandler = true;

          simulatedEvent.initMouseEvent(event.type, true, true, window, 1, event.screenX, event.screenY, event.clientX, event.clientY, false, false, false, false, 0/*left*/, null);
          
          objects[i].dispatchEvent(simulatedEvent);
        }
      }
    }
  };
};

var VC = {
    projectStartPage: null,
    
    returnTimer: null,
    showStartPageAt: -1,
    returnToStartPageDelay: 0,
    
    currentPopupPage: null,
    
    checkTimer: function() {
      if(VC.showStartPageAt == -1) return;
      
      if(new Date().getTime() >  VC.showStartPageAt) {
        VC.showStartPageAt = -1;
        showPage(VC.projectStartPage);
      }
    },
    setReturnToStartPage: function(delay) {
      VC.returnToStartPageDelay = delay;
      if(delay > 0) {
        if(VC.returnTimer === null) {
          VC.returnTimer = window.setInterval("VC.checkTimer()", 5000);
        }
      } else {
        if(this.returnTimer !== null) {
          window.clearInterval(VC.returnTimer);
          VC.returnTimer = VC;
        }
      }
    },
    retriggerReturnToStartPage: function() {
      VC.showStartPageAt = new Date().getTime() + VC.returnToStartPageDelay;
    },

    /**
     * 
     * @param popupPage
     */
    showPopupPage: function(popupPage) {
      if(VC.currentPopupPage != null) {
        if(VC.currentPopupPage === popupPage) {
          return;
        }
        closePopupPage();
      }
      
      if(!popupPage.hasBeenLoaded) {
        loadPage(popupPage, function onFinish(){
          VC.showPopupPage(popupPage);
        });
        return;
      }
      var pageWidth = popupPage.width;
      var pageHeight = popupPage.height;

      var popupBg = document.createElement("canvas");
      $(popupBg).attr("width", pageWidth + "px");
      $(popupBg).attr("height", pageHeight + "px");
      $(popupBg).css({
        popsition: "absolute",
        opacity: popupPage.bgAlpha / 100.0
      });
      $("#popup").append(popupBg);
      
      $("#popup").css({
        backgroundColor: "black",
        left:       ($("#page").width() - pageWidth) / 2 + "px",
        top:        ($("#page").height() - pageHeight) / 2 + "px",
        width:      pageWidth + "px",
        height:     pageHeight + "px",
        visibility: "visible"
      });
      
      $("#popup_close").attr("src", theme.getImagePath("imgCloseDialog"));
      $("#popup_close").css({
        left:       $("#popup").position().left + pageWidth + "px",
        top:        $("#popup").position().top - $("#popup_close").height() + "px",
        visibility: "visible"
      });
      
      $("#popup_background").css({
        left:       "0px",
        top:        "0px",
        width:      $("#page").width() + "px",
        height:     $("#page").height() + "px",
        visibility: "visible"
      });

//    VC.setPageParameter();
      
      var prevCategory = knxRefresher.getCurrentCategory();
      
      var knxCategory = "visu_embedded_" + popupPage.id;
      knxRefresher.setCurrentCategory(knxCategory);

      OC.showObjects(popupPage, $("#popup"), true);

      cacheObjects(knxCategory, popupPage);
      
      knxRefresher.setCurrentCategory(prevCategory);
      
      VC.currentPopupPage = popupPage;
    },
    
    /**
     * 
     */
    closePopupPage: function() {
      if(VC.currentPopupPage != null) {
        knxRefresher.clearCategory("visu_embedded_" + VC.currentPopupPage.id);
        knxRefresher.updateFilter();
        VC.currentPopupPage = null;
      }
      
      $("#popup").css("visibility", "hidden");
      $("#popup").empty();
      $("#popup_background").css("visibility", "hidden");
      $("#popup_close").css("visibility", "hidden");
    },

    /**
     * 
     * @param embedded
     * @param pageContent
     * @param embeddedPageOwner
     */
    showEmbeddedPage: function(embedded, pageContent, embeddedPageOwner) {
      var pageWidth = $(pageContent).width();
      var pageHeight = $(pageContent).height();

      var pageBg = document.createElement("canvas");
      $(pageBg).css({
            width: pageWidth+"px",
            height: pageHeight+"px",
            opacity: embedded.bgAlpha / 100.0
      });
      $(pageContent).append(pageBg);
      var context = pageBg.getContext('2d');
      VC.setPageBackground(embedded, context, pageWidth, pageHeight, false);

      var prevCategory = knxRefresher.getCurrentCategory();

      var knxCategory = "visu_embedded_"+embedded.id;
      knxRefresher.setCurrentCategory(knxCategory);

      OC.showObjects(embedded, pageContent, true);

      cacheObjects(knxCategory, embedded);
      
      knxRefresher.setCurrentCategory(prevCategory);
    },

    /**
     * 
     * @param embedded
     */
    hideEmbeddedPage: function(embedded) {
      knxRefresher.clearCategory("visu_embedded_"+embedded.id);
    },
    
    /**
     * 
     */
    setPageParameter: function() {
      var refPage;

      if(currentPage.masterId == -1) {
        refPage = currentPage;
      } else {
        refPage = currentMaster;
      }
      
      var pageWidth = refPage.width;
      var pageHeight = refPage.height;
      
      $("#page").css({
        visibility: "visible",
        width: pageWidth + "px",
        height: pageHeight + "px"
      });
      
      if (currentPage.masterId == -1 || currentPage.borderOverride) {
        refPage = currentPage;
      } else {
        refPage = currentMaster;
      }
      if (refPage.borderPageColor) {
        if (refPage.bgStyle.bgType == BG_TYPE_SOLID) {
          $("#body").css("background-color", refPage.bgStyle.solidColor);
        } else {
          $("#body").css("background-color", refPage.bgStyle.gradientColor1);
        }
      } else {
        $("#body").css("background-color", refPage.borderColor);
      }
      
      if(currentPage.masterId == -1 || currentPage.bgOverride) {
        refPage = currentPage;
      } else {
        refPage = currentMaster;
      }
      var pageBg = document.getElementById("canvasPageBackground");
      if (pageBg == undefined) {
        pageBg = document.createElement("canvas");
        $(pageBg).attr("id", "canvasPageBackground");
        $("#page").append(pageBg);
      }
      $(pageBg).attr("width", pageWidth);
      $(pageBg).attr("height", pageHeight);

      var context = pageBg.getContext('2d');
      VC.setPageBackground(refPage, context, pageWidth, pageHeight, true);
    },
    /**
     * 
     * @param refPage
     * @param context
     * @param pageWidth
     * @param pageHeight
     * @param drawBorder
     */
    setPageBackground: function(refPage, context, pageWidth, pageHeight, drawBorder) {
      var strokeColor = null;
      var bgStyle = refPage.bgStyle;

      if(bgStyle.bgSettings === BG_SETTINGS_THEME) {
          switch(theme.getPropertyInt("pageBgType", Theme.THEME_BACKGROUND_GRADIENT)) {
            case BG_TYPE_NONE:
              break;
            case BG_TYPE_SOLID:
              context.fillStyle = theme.getPropertyColor("pageBgColor1", "#ffffff");
              context.fillRect(0, 0, pageWidth, pageHeight);
              strokeColor = context.fillStyle;
              break;
            case BG_TYPE_GRADIENT:
              var lingrad = context.createLinearGradient( 0, 0, 0, pageHeight );
              lingrad.addColorStop( 0, theme.getPropertyColor("pageBgColor1", "#ffffff") );
              lingrad.addColorStop( 1, theme.getPropertyColor("pageBgColor2", "#dddddd"));
              context.fillStyle = lingrad;
              context.fillRect(0, 0, pageWidth, pageHeight);
              strokeColor = theme.getPropertyColor("pageBgColor1", "#ffffff");
              break;
          }
      }
      if(bgStyle.bgSettings === BG_SETTINGS_MANUAL) {
        if(bgStyle.bgType === BG_TYPE_SOLID) {
            context.fillStyle = bgStyle.bgColor1;
            strokeColor = bgStyle.bgColor1;
        }
        if(bgStyle.bgType === BG_TYPE_GRADIENT) {
            var lingrad = bgStyle.gradientType  === BG_GRADIENTTYPE_VERTICAL ? 
                    context.createLinearGradient( 0, 0, 0, pageHeight) :
                    context.createLinearGradient( 0, 0, pageWidth, 0);
            lingrad.addColorStop( 0, bgStyle.bgColor1 );
            lingrad.addColorStop( 1, bgStyle.bgColor2 );
            context.fillStyle = lingrad;
            strokeColor = bgStyle.bgColor1;
        }
      }
      context.fillRect(0, 0, pageWidth, pageHeight);

      var item = imagePool.getItem(refPage.bgPattern);
      if (item != null) {
        var image = new Image();
        image.onload = function() {
            switch(refPage.bgAlignment) {
              case BG_ALIGN_CENTERED:
                context.drawImage(image, 
                          (pageWidth - item.width) / 2, (pageHeight - item.height) / 2, item.width * DPR, item.height * DPR);
                break;
              case BG_ALIGN_STRETCHED:
                context.drawImage(image, 0, 0, pageWidth * DPR, pageHeight * DPR);
                break;
              case BG_ALIGN_TITLED:
                for(var x = 0; x < pageWidth; x += item.width * DPR) {
                  for(var y = 0; y < pageHeight; y += item.height * DPR) {
                    context.drawImage(image, x, y, item.width * DPR, item.height * DPR);
                  }
                }
                break;
            }
        };
        image.src = imagePool.getImagePath(refPage.bgPattern);
      }

      if(drawBorder && strokeColor != null) {
          context.strokeStyle = getBorderColor(strokeColor);
          context.strokeRect(0, 0, pageWidth, pageHeight);
      }
    }
};
