var MyStyle;
if(!MyStyle) MyStyle = {};

/*
 * MyStyle.Page
 */
MyStyle.Page = {
  init: function() {
    this.args = Object.extend(this.getArgs(), {});
  },
  load: function() {
    this.cookieManager = Mokkotsu.Page.getCookieManager();
    var static_vol = this.cookieManager.getCookie('static_vol');
    var static_tag = this.cookieManager.getCookie('static_tag');
    if(static_vol || static_tag) {
      try{
        MyStyle.Page.args.vol = static_vol;
        MyStyle.Page.args.tag = static_tag;
        this.cookieManager.clearCookie('static_vol');
        this.cookieManager.clearCookie('static_tag');
        Searcher.Page.infomationPanel.collapse();
      }catch(e){
        // throw e;
      }
    }

    var archive =  this.cookieManager.getCookie('archive');
    if(archive) {
      try{
        MyStyle.Page.args.archive = archive;
        this.cookieManager.clearCookie('archive');
        Searcher.Page.infomationPanel.collapse();
      }catch(e){
        // throw e;
      }
    }

    if(MyStyle.Page.args.static) {
      if(!MyStyle.Page.args.tag) MyStyle.Page.args.tag = '';
    }
    new MyStyle.Manager();
  },
  getArgs: function() {
    var args = {};
    if(window.location.search.length == 0) return args;
    window.location.search.substring(1).split('&').each(function(value) {
      var pair = value.split('=');
      args[pair[0].toLowerCase()] = decodeURIComponent(pair[1]);
    });
    return args;
  }
};
MyStyle.Page.init();
document.observe('dom:loaded', MyStyle.Page.load.bind(MyStyle.Page));

/*
 * MyStyle.Manager
 */
MyStyle.Manager = Class.create({
  initialize: function() {
    this.node = $('mystyle').down('.gadget');
    if(MyStyle.Page.args.static) {
      if(MyStyle.Page.args.archive) {
        this.request({archive:MyStyle.Page.args.archive});
      }else if(MyStyle.Page.args.series) {
        this.request({vol:MyStyle.Page.args.vol, series:MyStyle.Page.args.series});
      }else{
        this.request({vol:MyStyle.Page.args.vol});
      }
    }else{
      this.node.down('.loader').show();
      var option = {};
      if(MyStyle.Page.args.archive) option.archive = MyStyle.Page.args.archive;
      else option.vol = MyStyle.Page.args.vol;
      this.request(option);
    }
  },
  /**
   * Ajax request
   */
  request: function(opt) {
    var params = Object.extend({
      vol: null,
      archive: null,
      series: null,
      datetime: (new Date()).getTime()
    }, opt || { });
    new Ajax.Request('/cgi-bin/ms_gadget.cgi', {
      method: 'get',
      parameters: params,
      onComplete: this.requestComplete.bindAsEventListener(this)
    });

    if(params.vol) MyStyle.Page.args.vol = params.vol;
    MyStyle.Page.args.archive = params.archive;
  },
  /**
   * Ajax requestComplete
   */
  requestComplete: function(xhr) {
    var obj = xhr.responseText.evalJSON();
    this.build(obj);
    this.display();
  },
  display: function() {
    if(MyStyle.Page.args.static) {
      this.layoutStatic();
    }else if(MyStyle.Page.args.tag){
      this.layout.curry({ tagOrder:MyStyle.Page.args.tag }).bind(this).delay(0.7);
      MyStyle.Page.args.tag = '';
    }else{
      this.layout.bind(this).delay(0.7);
    }
  },
  build: function(obj) {
    this.json = obj;
    $('mystyle').className = 'clearfix';

    // タグ別のコンテンツ数を数える
    this.json.gadget_list.count_by_tag_id = function(tag_id) {
      var count = 0;
      this.json.gadget_list.each(function(item){ if(item.tag_id == tag_id) count++; });
      return count;
    }.bind(this);

    // タグ別のアーカイブのコンテンツ数を取得」
    this.json.gadget_list.archive_count_by_tag_id = function(tag_id) {
      var count = 0;
      this.json.archive_list.each(function(item){ if(item.tag_id == tag_id) count = item.count; });
      return count;
    }.bind(this);

    var oldTitle;
    if(this.titleGadget) oldTitle = this.titleGadget.node;
    this.titleGadget = new MyStyle.TitleGadget(this);
    this.titleGadget.build();
    if(oldTitle) oldTitle.remove();

    this.gadgetList = [];
    if(!(MyStyle.Page.args.static && MyStyle.Page.args.archive)) {
      if(MyStyle.Page.args.series && this.json.series_list) {
        this.series = new MyStyle.Series(this);
        this.series.build();
      }else{
        this.json.gadget_list.each(function(item){
          var gadget = new MyStyle.Gadget(this);
          gadget.build(item);
          this.gadgetList.push(gadget);
        }.bind(this));
      }
    }
  },
  layout: function(opt) {
    var options = Object.extend({
      tagOrder: null,
      tagOnly: false,
      ignorePriority: false,
      columnCount: 5
    }, opt || { });

    var effects = [];
    var columns = new Array(options.columnCount);
    for (var i = 0; i < columns.length; ++i) columns[i] = 0;
    columns[0] = this.titleGadget.node.getHeight() + 15;

    var list = this.gadgetList;
    if(!MyStyle.Page.args.archive){
      // アーカイブ以外は、シャッフルしてからソート
      var DEFAULT_ORDER = 999999999;
      list = list.shuffle().sortBy(function(gadget){

        if(options.tagOrder) {
          if(gadget.tag_id == options.tagOrder) return 10;
        }else if(!options.ignorePriority) {
          if(!gadget.order) return DEFAULT_ORDER;
          return gadget.order;
        }
        return DEFAULT_ORDER;
      }.bind(this));
    }

    list.each(function(gadget){
      if(options.tagOnly) {
        // 特定のタグ以外除去
        if(gadget.tag_id != options.tagOrder) return;
        var top = 0;
        var left = 915;
        effects.push(new Effect.Move(gadget.node, { x: left, y: top, mode: 'absolute', sync: true }));
      }else{
        // 通常の画面内で再配置
        var index = this.getShortest(columns);
        var top = columns[index];
        var left = (gadget.node.getWidth() + 15) * index;
        effects.push(new Effect.Move(gadget.node, { x: left, y: top, mode: 'absolute', sync: true }));
        columns[index] += gadget.node.getHeight() + 15;

        if(options.tagOrder && (gadget.tag_id != options.tagOrder)) {
          if(!gadget.isGrayed()) effects.push(new Effect.Appear(gadget.surface, { from:0, to:0.3, sync: true, afterFinish: function(){ gadget.node.addClassName('grayed'); }}));
        }else{
          if(gadget.isGrayed()) effects.push(new Effect.Fade(gadget.surface, { from:0.3, to:0, sync: true, beforeStart: function(){ gadget.node.removeClassName('grayed'); }}));
        }
        if(options.tagOrder) {
          if(this.titleGadget.member && !this.titleGadget.memberGray.visible()) effects.push(new Effect.Appear(this.titleGadget.memberGray, { from:0, to:0.3, sync: true, afterFinish: function(){ this.titleGadget.member.down('.content.item').addClassName('grayed'); }.bind(this)}));
          if(this.titleGadget.archives && !this.titleGadget.archivesGray.visible()) effects.push(new Effect.Appear(this.titleGadget.archivesGray, { from:0, to:0.3, sync: true, afterFinish: function(){ this.titleGadget.archives.down('.content.item').addClassName('grayed'); }.bind(this)}));
        }else{
          if(this.titleGadget.member && this.titleGadget.memberGray.visible()) effects.push(new Effect.Fade(this.titleGadget.memberGray, { from:0.3, to:0, sync: true, beforeStart: function(){ this.titleGadget.member.down('.content.item').removeClassName('grayed'); }.bind(this)}));
          if(this.titleGadget.archives && this.titleGadget.archivesGray.visible()) effects.push(new Effect.Fade(this.titleGadget.archivesGray, { from:0.3, to:0, sync: true, beforeStart: function(){ this.titleGadget.archives.down('.content.item').removeClassName('grayed'); }.bind(this)}));
        }
      }
    }.bind(this));

    var height = columns[this.getHighest(columns)];
    effects.push(new Effect.Morph(this.node, { style:'height:' + height + 'px;', sync: true }));
    effects.push(new Effect.Fade(this.node.down('.loader'), { sync: true }));
      new Effect.Parallel(effects, {
      duration: 0.5,
      transition: Effect.Transitions.sinoidal,
      queue: { scope: 'layout_gadget', limit: 1 }
    });
    this.keepButton = false;
  },
  getShortest: function(array) {
    var index = -1;
    for (var i = 0; i < array.length; ++i) {
      if(index < 0) index = i;
      if(array[i] < array[index]) index = i;
    }
    return index;
  },
  getHighest: function(array) {
    var index = -1;
    for (var i = 0; i < array.length; ++i) {
      if(index < 0) index = i;
      if(array[i] > array[index]) index = i;
    }
    return index;
  },
  layoutStatic: function() {
    this.gadgetList.each(function(gadget) {
      if(MyStyle.Page.args.tag.toString() !== gadget.tag_id) return;
      gadget.node.show();
    });
  },
  wipeout: function(opt) {
    var params = Object.extend({
      keepButton: false
    }, opt || { });
    this.keepButton = params.keepButton;

    var effects = [];
    this.node.down('.loader').show();

    this.gadgetList.each(function(gadget){
      var position = MyStyle.Gadget.getRandomPosition();
      effects.push(new Effect.Move(gadget.node, { x: position.left, y: position.top, mode: 'absolute', sync: true }));
    }.bind(this));

    if(!this.keepButton) this.titleGadget.hideButton();
      new Effect.Parallel(effects, {
      duration: 0.5,
      transition: Effect.Transitions.sinoidal,
      afterFinish: function(){
        this.gadgetList.each(function(gadget) { gadget.node.remove(); });
      }.bindAsEventListener(this)
    });
  },
  grayOffAll: function(){
    var grayOff = function(g){
      if(!g.surface.visible()) return;
      g.surface.fade({
        duration: 0.2,
        transition: Effect.Transitions.linear,
        beforeStart: function(){
          g.node.removeClassName('grayed');
        }.bind(this)
      });
    }
    this.gadgetList.each(grayOff);
    if(this.titleGadget.archives) grayOff({surface:this.titleGadget.archivesGray, node:this.titleGadget.archives.down('.content.item')});
    if(this.titleGadget.member) grayOff({surface:this.titleGadget.memberGray, node:this.titleGadget.member.down('.content.item')});
  }
});

/*
 * MyStyle.TitleGadget
 */
MyStyle.TitleGadget = Class.create({
  DEFAULT_ARCHIVE_TAG_ID: '1',
  initialize: function(manager) {
    this.manager = manager;
  },
  build: function(){
    this.node = $(Builder.node('div', { className:'title_container' }));
    this.manager.node.insert(this.node);


    if(MyStyle.Page.args.static && MyStyle.Page.args.archive) {
      // 「一覧へ戻る」
      this.listButton =
        $(Builder.node('div', { className:'upper back_button' },
          Builder.node('a', { href:'javascript:void(0);', className:'button' },
            Builder.node('img', { src:'/common/imgs/goto_list_off.gif' })
          )
        ));
      this.listButton.down('a').observe('click', function(){
        var cookieManager = Mokkotsu.Page.getCookieManager();
        cookieManager.setCookie('archive', MyStyle.Page.args.archive);
        window.location = '/';
      }.bindAsEventListener(this));
      Mokkotsu.Page.setupButton(this.listButton.down('a'));
    }else if(!(this.manager.json.is_newest && !MyStyle.Page.args.static)) {
      var src = this.manager.json.is_newest ? 'goto_top_off.gif' : 'goto_newest_off.gif';
      // 「最新号へ戻る」
      this.newestButton =
        $(Builder.node('div', { className:'upper back_button', style:'display:none' },
          Builder.node('a', { href:'javascript:void(0);', className:'button' },
            Builder.node('img', { src:'/common/imgs/' + src })
          )
        ));
      this.newestButton.down('a').observe('click', function(){
        if(MyStyle.Page.args.static) {
          window.location = '/';
        }else{
          this.manager.wipeout();
          this.manager.request.bind(this.manager).delay(0.5);
        }
      }.bindAsEventListener(this));
      Mokkotsu.Page.setupButton(this.newestButton.down('a'));
    }

    // コンテンツ
    this.title =
      $(Builder.node('div', { className:'title item vol' + this.manager.json.volume_id }, [
        Builder.node('p', Builder.node('img', { src:'/common/imgs/mystyle_sidetitle.gif', alt:'木の家 My Style', className:'gadget_image' })),
        Builder.node('p', { className:'volume' }, this.manager.json.volume_name),
        Builder.node('p', Builder.node('img', { src:'/common/imgs/side_contents.gif', alt:'contents', className:'gadget_image' })),
        Builder.node('div', { className:'tag_list' }, this.buildTagList()),
        Builder.node('div', { className:'volume_list' }, this.buildVolumeList())
      ]));

    if(!MyStyle.Page.args.static || (MyStyle.Page.args.static && MyStyle.Page.args.archive)) {
      // 新規Style会員お申し込み
      this.memberGray = $(Builder.node('div', { className:'surface', style:'display:none' }));
      this.member =
        $(Builder.node('div', { className:'lower' },
          Builder.node('div', { className:'content fixed item vol0' }, [
            this.memberGray,
            Builder.node('p', Builder.node('img', { className:'gadget_image', src:'/common/resources/imgs/Gadget_v0_touroku.jpg' })),
            Builder.node('div', { className:'text_content' }, Builder.node('p', { className:'size_s' }, 'ライフスタイル情報誌『木の家 My Style』を毎号無料でお届けします。ご希望の方はこちらから。'))
          ])
        ));
      this.member.down('.content.item').observe('click', function(){
        if(this.member.down('.content.item').hasClassName('grayed')) {
          this.manager.grayOffAll();
        }else{
          window.location = '/about/style_member.html';
        }
      }.bindAsEventListener(this));
    }

    if(!MyStyle.Page.args.static && this.manager.json.is_newest) {
      // アーカイブ
      this.archivesGray = $(Builder.node('div', { className:'surface', style:'display:none' }));
      this.archives =
        $(Builder.node('div', { className:'lower' },
          Builder.node('div', { className:'content fixed item vol0' }, [
            this.archivesGray,
            Builder.node('p', Builder.node('img', { className:'gadget_image', src:'/common/resources/imgs/Gadget_v0_archive.jpg' })),
            Builder.node('div', { className:'text_content' }, Builder.node('p', { className:'size_s' }, 'カテゴリー別のガジェット一覧をご覧いただけます。'))
          ])
        ));
      this.archives.down('.content.item').observe('click', function(){
        if(this.archives.down('.content.item').hasClassName('grayed')) {
          this.manager.grayOffAll();
        }else{
          this.archives.down('.content.item').stopObserving('click');
          this.manager.wipeout();
          this.manager.request.curry({archive:this.DEFAULT_ARCHIVE_TAG_ID}).bind(this.manager).delay(0.5);
        }
      }.bindAsEventListener(this));
    }

    var usingEffectForButton = (this.manager.keepButton || MyStyle.Page.args.static);

    if(usingEffectForButton) {
      if(this.newestButton) this.newestButton.show();
    }

    if(this.newestButton) this.node.insert(this.newestButton);
    if(this.listButton) this.node.insert(this.listButton);
    this.node.insert(this.title);
    this.node.insert(this.member);
    if(this.archives) this.node.insert(this.archives);

    if(!usingEffectForButton) {
      this.node.down('.volume').setStyle({ cursor:'pointer' });
      this.node.down('.volume').observe('click', this.manager.layout.bindAsEventListener(this.manager));

      this.showButton.bind(this).delay(0.5);
    }
    this.node.down('.volume_list select').observe('change', this.changeVolume.bindAsEventListener(this));
    this.node.select('.volume_list select option').first().selected = true;
  },
  showButton: function() {
    if(this.newestButton) new Effect.BlindDown(this.newestButton, this.displayButtonOptions);
    // if(this.archives) new Effect.BlindDown(this.archives, this.displayButtonOptions);
    // if(this.member) new Effect.BlindDown(this.member, this.displayButtonOptions);
  },
  hideButton: function() {
    if(this.newestButton) new Effect.BlindUp(this.newestButton, this.displayButtonOptions);
    // if(this.archives) new Effect.BlindUp(this.archives, this.displayButtonOptions);
    // if(this.member) new Effect.BlindUp(this.member, this.displayButtonOptions);
  },
  displayButtonOptions: {
    duration: 0.2,
    transition: Effect.Transitions.linear
  },
  buildTagList: function() {
    var list = [];
    this.manager.json.tag_list.each(function(tag) {
      var count = this.manager.json.gadget_list.count_by_tag_id(tag.tag_id);
      if(MyStyle.Page.args.archive) count = this.manager.json.gadget_list.archive_count_by_tag_id(tag.tag_id);

      // 0件のカテゴリーは非表示にする
      if(!count) return;

      var anchor =
        Builder.node('a', { href:'javascript:;' },[
          Builder.node('img', { src:'/common/imgs/side_category_' + tag.tag_name.toLowerCase() + '_off.gif', alt:'' })
        ]);
      Mokkotsu.Page.setupButton(anchor);
      $(anchor).observe('click', function(event){
        if(!count) return;
        if(MyStyle.Page.args.archive) {
          if(MyStyle.Page.args.static) {
            var cookieManager = Mokkotsu.Page.getCookieManager();
            cookieManager.setCookie('archive', tag.tag_id);
            window.location = '/';
          }else{
            this.manager.wipeout({keepButton: true});
            this.manager.request.curry({archive:tag.tag_id}).bind(this.manager).delay(0.5);
          }
        }else if(MyStyle.Page.args.static) {
          var cookieManager = Mokkotsu.Page.getCookieManager();
          cookieManager.setCookie('static_vol', MyStyle.Page.args.vol);
          cookieManager.setCookie('static_tag', tag.tag_id);
          window.location = '/';
          event.stop();
        }else{
          this.manager.layout({ tagOrder:tag.tag_id });
        }
      }.bindAsEventListener(this));

      var li = $(Builder.node('li', { className:'tag' + tag.tag_id, tag_id:tag.tag_id }, anchor));
      list.push(li);
    }.bind(this));
    return Builder.node('ul', { className:'tags' }, list);
  },
  buildVolumeList: function() {
    var list = [];
    list.push(Builder.node('option', { selected:'selected', value:'' }, 'バックナンバー'));
    this.manager.json.backnumbers.each(function(backnumber) {
      if(!MyStyle.Page.args.archive && this.manager.json.volume_id == backnumber.volume_id) return;
      list.push(Builder.node('option', { value:backnumber.volume_id }, backnumber.volume_name));
    }.bind(this));
    return Builder.node('select', { name:'volume' }, list);
  },
  changeVolume: function() {
    var vol = this.node.down('.volume_list select').value;
    if(vol == '') {
      return;
    }else if(vol == '13') {
      window.location = '/gadget/my_style/backnumber/index.html';
      return;
    }else if(MyStyle.Page.args.static) {
      var cookieManager = Mokkotsu.Page.getCookieManager();
      cookieManager.setCookie('static_vol', vol);
      window.location = '/';
      return;
    }else{
      this.node.down('.volume_list select').disabled = true;
      this.manager.wipeout();
      this.manager.request.curry({vol:vol}).bind(this.manager).delay(0.5);
    }
  }
});

/*
 * MyStyle.Gadget
 */
MyStyle.Gadget = Class.create({
  initialize: function(manager) {
    this.manager = manager;
  },
  build: function(obj) {
    var list = [];
    list.push(this.buildTextContent(obj, 'size_m'));
    list.push(this.buildTextContent(obj, 'size_l'));
    list.push(this.buildTextContent(obj, 'size_s'));
    list.push(this.buildTextContent(obj, 'body'));
    list = list.compact();

    var underImage = [];
    if(obj.tag_name) underImage.push(Builder.node('img', { src:'/common/imgs/toptag_' + obj.tag_name.toLowerCase() + '.gif', alt:'' }));
    underImage.push(Builder.node('span', obj.display_date));

    this.gadget_id = obj.gadget_id;
    this.tag_id = obj.tag_id;
    this.order = obj.volume_order;

    this.surface = $(Builder.node('div', { className:'surface', style:'display:none' }));
    this.node =
      $(Builder.node('div', { className:'content item tag' + obj.tag_id + ' ' + obj.gadget_id }, [
        this.surface,
        Builder.node('p', Builder.node('img', { src:obj.picture, alt:'', className:'gadget_image' })),
        Builder.node('p', { className:'tagdate clearfix' }, underImage),
        Builder.node('div', { className:'text_content' }, list)
      ]));
    this.node.addClassName('vol' + obj.volume_id);
    this.manager.node.insert(this.node);
    if(MyStyle.Page.args.static) {
      this.node.setStyle({ display:'none' });
    }else{
      var position = MyStyle.Gadget.getRandomPosition();
      this.node.setStyle({ left: position.left + 'px', top: position.top + 'px'});
    }

    this.node.observe('click', function(){
      if(this.node.hasClassName('grayed')) {
        this.manager.grayOffAll();
      }else{
        var url = obj.url;
        if(MyStyle.Page.args.archive) url += '?archive=' + MyStyle.Page.args.archive;
        if(obj.new_window == '1') window.open(obj.url);
        else window.location = url;
      }
    }.bindAsEventListener(this));
  },
  buildTextContent: function(obj, key) {
    if(!obj[key]) return null;
    return $(Builder.node('p', { className:key })).update(obj[key]);
  },
  isGrayed: function() {
    return this.surface.visible();
  }
});

/*
 * Static
 * MyStyle.Gadget
 */
Object.extend(MyStyle.Gadget, {
  getRandomPosition: function() {
    var position = { left:-183, top:0};
    if(Math.round(Math.random() * 1)) position.left = 915;
    if(Math.round(Math.random() * 1)) position.top = document.viewport.getHeight();
    return position;
  }
});

/*
 * MyStyle.Series
 */
MyStyle.Series = Class.create({
  initialize: function(manager) {
    this.manager = manager;
  },
  build: function() {
    var list = [];
    this.manager.json.series_list.each(function(item, index) {
      var anchor = $(Builder.node('a', { href:item.url })).update(item.series_title);
      if(index + 1 == MyStyle.Page.args.series_selected) anchor.addClassName('selected');
      list.push(Builder.node('li', anchor));
    }.bind(this));
    list.reverse();

    this.node =
      $(Builder.node('div', { className:'item vol0' }, [
        this.surface,
        Builder.node('p', { className:'tagdate clearfix' },
          Builder.node('img', { src:'/common/imgs/toptag_' + this.manager.json.series_tag_name.toLowerCase() + '.gif', alt:'' })),
        Builder.node('div', { className:'series_content' }, [
          $(Builder.node('p', { className:'title' })).update(this.manager.json.series_name),
          Builder.node('ul', { className:'' }, list)
        ])
      ]));
    this.manager.node.insert(this.node);
  }
});

Array.prototype.shuffle = function() {
  return this.sortBy(Math.random);
};

