//
//
//
function loadStreetViewFunctions(namespace, ci) {
  (function() {
    var contentsIndex = ci;
    var baseDiv;

    // div 要素
    var dispatcher; // ディスパッチャー (swf)
    var pano;       // プレイヤー (swf)
    var map;
    var panorama;   
    var panoClient;
    
    var currentLatlng;
    var nextLatlng;
    var currentPOV;
    var currentPanoID;
    var nextPanoID;

    //
    //
    //
    function makeHtml(aBaseDiv) {
      //
      baseDiv = aBaseDiv;
      var div = baseDiv;

      var date = new Date();

      // Dispatcher Flash を表示する
      div.append('<div id="dispatcher' + contentsIndex + '"></div>');
      showDispatcherFlash(contentsIndex, '/streetview/StreetViewSub.swf', "dispatcher" + contentsIndex, namespace);

      // パノラマを表示する
      div.append('<div id="pano' + contentsIndex + '" style="width: 600px; height: 338px;"></div>');
      pano = div.find('#pano' + contentsIndex);

      // 地図
      div.append('<div id="map_canvas' + contentsIndex + '" style="width: 600px; height: 100px;"></div>');
    }

    //
    var loadCount = 0;
    function loaded(t) {
      loadCount++;
      if (loadCount >= 1) {
        namespace.dispatcher.sendLoaded();
      }
    }

    // 初期化
    function initTour(lat, lng, yaw, pitch, zoom) {
      // 位置設定
      currentLatlng = new GLatLng(lat, lng);
    
      // 向き設定
      currentPOV = {};
      currentPOV.yaw   = yaw;
      currentPOV.pitch = pitch;
      currentPOV.zoom  = zoom;
    
      // パノラマクライアント生成
      panoClient = new GStreetviewClient();      
    
      // 地図生成
      map = new GMap2(document.getElementById("map_canvas" + contentsIndex));
      map.enableGoogleBar();
      map.enableScrollWheelZoom();
    
      // 地図と同期
      map.setCenter(currentLatlng, 15);
    
      // ストリートビューオーバーレイ追加
      svOverlay = new GStreetviewOverlay();
      map.addOverlay(svOverlay);
    
      // 地図がクリックされたらストリートビューに反映させる
      GEvent.addListener(map, "click", function(overlay, currentLatlng) {
        panoClient.getNearestPanorama(currentLatlng, showPanoData);
      });
    
      // パノラマ生成
      panorama = new GStreetviewPanorama(document.getElementById("pano" + contentsIndex));
    
      // パノラマの位置と向き設定
      panorama.setLocationAndPOV(currentLatlng, currentPOV);
    
      // パノラマの状態変化時のイベント設定
      GEvent.addListener(panorama, "initialized",  handleInitialization);
      GEvent.addListener(panorama, "yawchanged",   handleYawChanged);
      GEvent.addListener(panorama, "pitchchanged", handlePitchChanged);
      GEvent.addListener(panorama, "zoomchanged",  handleZoomChanged);
      GEvent.addListener(panorama, "error",        handleNoFlash);
    
      panoClient.getNearestPanorama(currentLatlng, showPanoData);
    }
    
    // 移動完了の検知
    function handleInitialization(location) {
      currentLatlng = location.latlng;
      currentPanoID = location.panoId;
    
      // 地図と同期
      map.setCenter(currentLatlng, 15);
    
      // 移動完了をサーバーに通知
      namespace.dispatcher.callFlash("move " + location.panoId + " " + location.latlng.lat() + " " + location.latlng.lng());
    }
    
    // クライアント内で yaw の変化を検知
    function handleYawChanged(yaw) {
      currentPOV.yaw = yaw;
    
      namespace.dispatcher.callFlash("pov " + currentPOV.yaw + " " + currentPOV.pitch + " " + currentPOV.zoom);
    }
    
    // クライアント内で pitch の変化を検知
    function handlePitchChanged(pitch) {
      currentPOV.pitch = pitch;
    
      namespace.dispatcher.callFlash("pov " + currentPOV.yaw + " " + currentPOV.pitch + " " + currentPOV.zoom);
    }
    
    // クライアント内で zoom の変化を検知
    function handleZoomChanged(zoom) {
      currentPOV.zoom = zoom;
    
      namespace.dispatcher.callFlash("pov " + currentPOV.yaw + " " + currentPOV.pitch + " " + currentPOV.zoom);
    }
    
    // サーバーから位置移動の通知を受け取った
    function move(panoid, lat, lng) {
      //
      if (panoid == currentPanoID) {
        return;
      }
    
      //
      nextPanoID = panoid;
      nextLatlng = new GLatLng(lat, lng); // 隣接の移動ができなかった場合に直接移動させるため
      panoClient.getNearestPanorama(currentLatlng, find_follow_link);
    }
    
    // サーバーから移動の指示があった場合にそれに従って移動する
    function find_follow_link(panoData) {
      //
      if (panoData.code != 200) {
        return;
      }

      //
      var i;
      var match = false;
      for (i = 0; i < panoData.links.length; i++) {
        if (nextPanoID == panoData.links[i].panoId) {
          // リンクを使って移動
          panorama.followLink(panoData.links[i].yaw);
          match = true;
        }
      }
    
      // 隣接の移動が追いつかない場合は強制的に移動させる
      if (match == false) {
        panorama.setLocationAndPOV(nextLatlng, currentPOV);
      }
    }
    
    // サーバーから pov を受け取った
    function pov(yaw, pitch, zoom) {
      currentPOV.yaw   = yaw   + 1 - 1;
      currentPOV.pitch = pitch + 1 - 1;
      currentPOV.zoom  = zoom  + 1 - 1;
      panorama.panTo(currentPOV);
    }
    
    // 地図クリックで移動
    function showPanoData(panoData) {
      if (panoData.code != 200) {
        return;
      }
    
      panorama.setLocationAndPOV(panoData.location.latlng);
    }
    
    // エラー
    function handleNoFlash(errorCode) {
      if (errorCode == 603) {
    //  alert("Error: Flash doesn't appear to be supported by your browser");
        return;
      }
    }
    
    // 公開する関数
    namespace.makeHtml = makeHtml;
    namespace.loaded   = loaded;

    //
    namespace.initTour = initTour;
    namespace.pov      = pov;
    namespace.move     = move;
  }) (namespace);
}
