

// Kniham javascript support
/* prototype */

var kniham = Class.create();

kniham.list = Class.create({
  initialize: function(options){
    this.name = 'Kniham';
    this.queue = new kutil.queue(this);
    this.autocompleter = new Ajax.Autocompleter(
        options.autocompleter_field
      , 'product_auto_complete'
      , options.product_load_url
      , {
          evalJS:true,
          frequency:0.4,
          minChars: 2,
          onCreate: function() { $('product').addClassName('ajaxactive'); },
          onSuccess: function() { $('product').removeClassName('ajaxactive'); }
      } );

/* override object */

    //Ajax.InPlaceCollectionEditor.prototype.__handleFormSubmission = Ajax.InPlaceEditor.prototype.handleFormSubmission;
    Object.extend( Ajax.InPlaceCollectionEditor.prototype, {
      handleFormSubmission: function(e) {
        var form = this._form;
        var value = $F(this._controls.editor);
        this.prepareSubmission();
        var params = this.options.callback(form, value ) || '';
        params.id  = this.element.id.substring(6);
        klist.queue.add( params ); //
        this._boundWrapperHandler();
        if (e) Event.stop(e);
      }
    });


    // redirect form submit event to queue

    this.executer = new PeriodicalExecuter( this.run.bind(this), 1  );

    this._action_url = options.action_url;
    this.categ_action_url = options.categ_action_url;
    this.options = options;
    this.categ_options = {
      collection: $A()
      , okText: kniham.i18n.category_ok
      , cancelText: kniham.i18n.category_cancel
      , savingText: kniham.i18n.category_saving
      , clickToEditText: kniham.i18n.category_click
      , callback: this._selectcategorycallback.bind(this)
    };
    this.setdate_options = {
          okText: kniham.i18n.category_ok
        , cancelText: kniham.i18n.category_cancel
        , savingText: kniham.i18n.category_saving
        , clickToEditText: kniham.i18n.click_to_edit
        , callback: this._setdatecallback.bind(this)
        , fieldPostCreation: false
      };
    this.catheaders = $H();
    /* Load categories hash */

    if( null != Categories ) {
      this.categ_options.collection = Categories;
    }
    else {
      new Ajax.Request( options.categ_list_url ,
        {
          onSuccess: function(response) { this.categ_options.collection = response.responseJSON; }.bind(this),
          onFailure: function(response) { this.categ_options.collection = new Array(); }.bind(this)
        }
      );
    }


    /* Init autoload */
    //$('products').select('div.item').each( this.initListElement.bind(this) );
    $('products').observe('click', this._onclick_handler.bind(this) );
    $('products').observe('mouseover', this._onmouseoverhandler.bind(this) );
    $('products').observe('mouseout', this._onmouseouthandler.bind(this) );
    $(options.autocompleter_form).observe( 'submit', this._onautocompletesubmit.bind(this) );
  },
  unload: function() { this.executer.stop(); },
  queue: null,
  executer:null,
  i:0,
  viewRange:'all',
  viewSort:1,
  run: function() {
    if( this.queue.size() > 0 ) {
      var _p = this.queue.getItems();
      /*
       * Send AJAX request, accept an element back
       */

      new Ajax.Request( this._action_url, { method: 'post'
        ,parameters: _p
        ,onSuccess: this._onAjaxSuccess.bind(this)
        ,onFailure: this._onAjaxFailure.bind(this)
        ,onException: this._onAjaxException.bind(this)
        ,asynchronous:true
        ,evalJS: true
        ,indicator:  'indicator'
          /*
        ,on302: fRedirect
          onUninitialized
          onLoading
          onLoaded
          onInteractive
          onComplete
          */
      });
    }
    else
    {
    }
  },

  initListElement: function(elem) {
    elem.observe('mouseover', this._onmouseoverhandler.bind(this) );
    elem.observe('mouseout', this._onmouseouthandler.bind(this) );
  }

  ,_onautocompletesubmit: function(evt) {
    var obj = $(this.options.autocompleter_field);
    if( !$F(obj).empty() ) {
      this.queue.add( { 'id':'new', 'todo':'newproduct', 'other': $F(obj) } );
      obj.value = '';
    } else {
      alert( kniham.i18n.empty_product );
    }
    evt.stop();
  },


  _onmouseoverhandler: function(evt) {
    var e = evt.findElement('div.item');
    if( null==e ) {
      return;
    }
    var b1 = e.getElementsBySelector('.hidden-buttons');
    if( b1 ) b1[0].show();
    //var h = obj.readAttribute('rel').split('_',2);

    //e.toggleClassName('closed');
    evt.stop();
  },


  _onmouseouthandler: function(evt) {
    var e = evt.findElement('div.item');
    if( null==e ) {
      return;
    }
    var b1 = e.getElementsBySelector('.hidden-buttons');
    if( b1 ) b1[0].hide();
    evt.stop();
  },


  /* Click handler for links */
  _linkclickhandler: function(evt) {
    var obj = evt.findElement();
    var h = obj.readAttribute('rel').split('_',2);
    this.queue.add( { 'id':h[1], 'todo':h[0] } );
    evt.stop();
  },

  /* listwide Click handler */
  _onclick_handler: function(evt) {
    var obj = evt.findElement();
    if( obj.tagName != 'A' ) return true;

    // get container
    var e = evt.findElement('div.item');
    if( null==e ) {
      e = evt.findElement('div.category');
      if( null==e ) {
        alert('Error 008 occured');
        return;
      }
    }
    var iteminfo = e.getAttribute('data').evalJSON( true );
    
    var act = obj.className;
    if(act.indexOf('mgt ')>-1 ) {
      act = act.substr(4);
    }
    
    switch(act) {
      case 'ct-hide':
        this._oncatheaderclick(e,iteminfo,evt);
        break;
      case 'pl-delay':
      case 'pl-today':
      case 'pl-cancel':
        act = act.substr(3);
        this.queue.add( { 'id':iteminfo.id, 'todo': act } );
        evt.stop();
        return false;
        break;
      case 'pl-categ':
        this._onselcategoryinit(obj);
        evt.stop();
        return false;
        break;
      case 'pl-delete':
        this._ondelete( iteminfo.id , evt);
        return false;
        break;
      case 'pl-setdate':
        this._onsetdate( obj, iteminfo.date );
        evt.stop();
        return false;
        break;
    }
    return true;

  }

  ,itemid: function(n) { return 'item_line_'+n; }
  ,catid:  function(n) { return 'cat_'+n; }

  ,_onselcategoryinit: function(elem, iiid ) {
    var editor = new Ajax.InPlaceCollectionEditor( elem, this.categ_action_url, this.categ_options );
    editor.enterEditMode();
    //editor.dispose();
  },


  _selectcategorycallback: function(f,v) {
    return { 'other':v, 'todo':'categ' };
  },

  _setdatecallback: function(f,v) {
    return { 'other':v, 'todo':'setdate' };
  },


  _oncategoryselect: function(h) {
      //this.queue.add( h );
  },



  _onAjaxFailure: function(response,json) {
    alert('Failure occured:'+response+"\n"+json );
  },

  _onAjaxException: function(req,ex) {
      throw(ex);
      alert('Exception occured:'+response+"\n"+json );
    },

  _onAjaxSuccess: function(response,json1) {

    if( null==json1['id'] )  {
      // probably session lost
      alert( "Please sign in again" ); 
      return; 
    }
    if( null==json1['act'] ) { alert( 'error 005' ); return; }


    var elem = this.itemid( json1['id'] );
    // clear autocompleter field
    if( null!=json1['clear'] ) {
        $('product').clear().focus();
    }

    switch( json1['act'] ) {
      case 'new':
        this.insertItem( response.responseText, json1 );
        break;

      case 'deleted':
        this.deleteItem( $(elem) );
        break;

      case 'changed':
        if( this.viewRange == 'all' ) {
          this.insertItem( response.responseText, json1 );
        }
        else if( this.viewRange =='today' ) {
          switch( json1['range'] ) {
            case 'today':
              // adding new element
              this.insertItem( response.responseText, json1 );
              break;
              //this.initListElement( $(elem) ); //.bind(this); // init new element
            case 'later':
              this.deleteItem( $(elem) );
          }
        }
      break;
    }
    return true;
  }

  /* Insert new item into appropriate category, or replace an existing one. Create category if needed */
  ,insertItem: function( htmlcode, json1 ) {
    var cat,elem1,elem2, targ;
    var newelemid = this.newprefix + this.itemid( json1['id'] );
    var elemid    = this.itemid( json1['id'] );
    
    // element to replace exists?
    if( $(elemid) ) {
      // todo: if categ.id = newcategid ...
      var iteminfo = $(elemid).getAttribute('data').evalJSON(true);
      if( json1['cat'] == iteminfo['cat'] ) {
        Element.replace( $(elemid), htmlcode );
        $(elemid).addClassName('changed');
        this.logAction( 'changed', null );
        return;
      } else {
        this.deleteItem( $(elemid) );
      }
    } 

    // category exists ?
    cat = this._container_id( json1['cat'] );
    targ = '';
    
    if( $(cat) ) {
      // category exists, insert new item
      elem2 = Element.insert( $(cat), { top: htmlcode } );
      new Effect.Highlight( elem2 );
      this.logAction( 'new', null );
    } else {
      if( this.viewSort != 3 ) {
        // insert new category
        var newcat = kdecorator.createCategory( json1['cat'], json1['catname'] );
        
        Element.insert( $('products'), { top: newcat } );
        targ = $(cat);
      }
      else {
        targ = $('products');
      }
      // insert element
      elem2 = Element.insert( targ, { top: htmlcode } );
      new Effect.Highlight( elem2 );
      this.logAction( 'new', null );
    }
    
    if( $('msg_no_products') ) Element.hide( $('msg_no_products') );

    return elem2;
    //this.initListElement( elem2 ); //.bind(this); // init new element
  }

  // delete an item and a category.
  ,deleteItem: function( elem ) {
    var iteminfo = elem.getAttribute('data').evalJSON(true);
    this.logAction('deleted');
    Effect.Fade( elem, { 
      afterFinish: function(eff) { 
        eff.element.remove(); 
        var i = $( 'catlst_'+iteminfo.cat ) ;
        if( null!=i && i.empty() ) {
          // delete category container
          i = $( 'cat_'+iteminfo.cat );
          //Effect.BlindUp(i, { afterFinish: function(eff) { eff.element.remove(); } } );
          i.remove();
        };
      } 
    });
  }
  
  
  ,logAction: function(action, message) {
    return;
    var msg = '';
    switch(action) {
      case 'deleted':
      case 'changed':
      case 'new':
        msg = 'fb_'+action;
    }        
    if(msg=='') return;
    console.log(msg);
    $('feedback-msg').innerHTML = kniham.i18n[msg];
    $('feedback-msg').show();
    Effect.Fade( $('feedback-msg'), { 
      afterFinish: function(eff) { 
        eff.element.innerHTML =''; 
      }
    } );
    
  }
  
  ,_container_id : function(catid) { return 'catlst_'+catid; }  
  
  ,_oncatheaderclick: function(elem,info,evt) {
      var lst = $('catlst_'+info['cat']);
      if( elem.hasClassName('category-closed') ) {
          Effect.BlindDown( lst );
      } else {
          Effect.BlindUp( lst );
      }
      elem.toggleClassName('category-closed');
      elem.toggleClassName('category-open');
      evt.stop();
  },
  
  _ondelete: function(item_id,evt) {
    
    if( confirm(kniham.i18n.qdelete) ) {
      this.queue.add( { 'id':item_id, 'todo':'delete' } );
    }
    evt.stop();
    return;
  },
  
  _onsetdate: function( elem, start_date ) {
    var editor = new Ajax.InPlaceDateEditor( elem, start_date, this.categ_action_url, this.setdate_options );
    editor.enterEditMode();
    //editor.dispose();
  }

});




var kdecorator = {
  createCategory: function(catcode,catname) {
    var elem_info = $H( {"items": 1,'cat':catcode} );
    
    var elem = new Element( 'div', {'id':'cat_'+catcode , 'class':'category category-open', 'data':elem_info.toJSON() } );
    var h3 = new Element( 'h3', {'class':'cathdr', 'id': 'cathdr_'+catcode } );
    var a  = new Element('a',{'class':'ct-hide','href':'#','title':kniham.i18n.open_close } );
    a.appendChild( document.createTextNode( ' ' ) );
    h3.appendChild( document.createTextNode( catname ) );
    h3.appendChild( a );
    elem.appendChild( h3 );
    var container = new Element('div', {'id': 'catlst_'+catcode, 'class':'catlist'} );
    elem.appendChild( container );
    return elem;
  }
};


var kutil = {
queue: Class.create({
  initialize: function(kniham_obj) {
    this._k = kniham_obj;
    this.clear();
  },
  _k    : null, /*niham_instance*/
  add   : function( hstr ) {
    hstr = $H( hstr );
    hstr.set('t',new Date().valueOf() );
    this._items.push( hstr );
    //console.log('queue.add '+hstr.inspect() );
  },

  size : function() { return this._items.size(); },

  getItems: function() {
    var t = new Date().valueOf();
    if( this.size() > 0 ) {
      p = this._items.shift();
      return p;
    } else {
      return null;
    }
  },

  clear: function() {
    this._items = [];
  }
})

};




Ajax.InPlaceDateEditor = Class.create(Ajax.InPlaceEditor, {
  initialize: function($super, element, start_date, url, options) {
    this._today = new Date();
    if( null==start_date || start_date.toString().length!=8 ) {
      start_date = this._today.getFullYear()+''+(1+this._today.getMonth())+''+this._today.getDate();
    }    
    this._start_date = start_date.toString();
    this._extraDefaultOptions = Ajax.InPlaceDateEditor.DefaultOptions;
    $super(element, url, options);
    
  },
  
  createEditField: function() {
    var y = this._today.getFullYear();
    var option;
    //01234567
    var cy = this._start_date.substr(0,4);
    var cm = this._start_date.substr(4,2);
    var cd = this._start_date.substr(6,2);
    
    var list2 = document.createElement('select');
    list2.name = 'sel_day';
    list2.size = 1;
    $R(1,31).each( function(v) {
      option = document.createElement('option');
      option.value = v;
      option.selected = ( cd == v );
      option.appendChild( document.createTextNode(v) );
      list2.appendChild( option );
    });

    // month index 1-12
    var list = document.createElement( 'select' );
    list.name = 'sel_month';
    list.size = 1;
    kniham.i18n.month_names.each(function(e,i) {
      option = document.createElement('option');
      option.value = e[0];
      option.selected = ( cm == e[0] );
      option.appendChild( document.createTextNode(e[1] ) );
      list.appendChild(option);
    });


    var list3 = document.createElement( 'select' );
    list3.name = 'sel_year';
    list3.size = 1;
    $R(y,y+1).each(function( v ) {
      option = document.createElement('option');
      option.value = v;
      option.selected = ( cy == v );
      option.appendChild( document.createTextNode( v ) );
      list3.appendChild(option);
    });
    
    var ed = document.createElement( 'span');
    ed.addClassName('pl-setdate'); 
    ed.appendChild( list2 );
    ed.appendChild( list );
    ed.appendChild( list3 );
    
    this._controls.editor = ed;
    
    this._form.appendChild( this._controls.editor );
    
  },
  
  
  handleFormSubmission: function(e) {
    var form = this._form;
    var value;
    Element.extend(form);
    value = $F(form.sel_year)+'-'+$F(form.sel_month)+'-'+$F(form.sel_day);
    this.prepareSubmission();
    var params = this.options.callback(form, value ) || '';
    params.id  = this.element.id.substring(8);
    klist.queue.add( params ); //
    this._boundWrapperHandler();
    if (e) Event.stop(e);
  }
  
  ,_start_date: null
  ,_today : null

  
});