/*
  Copyright (c) 2006-2010, ePages GmbH
  All Rights Reserved.

  +-----+---------------+--------------------
  |  _  |               |
  | |_| | tableHead[0]  | tableHead[1]  ...
  |_____|_______________|____________________
  |     |               |
  | |x| | content[0][0] | content[0][1] ...
  |_____|_______________|____________________
  |  .
  |  .
  |  .
  |__________________________________________
  |
  | Page x of y  |<  < 1 2 3 >  >|   Count: z
  +------------------------------------------

*/
dojo.provide("epages.cartridges.de_epages.product.widget.ProductPickerList");//an dieser Stelle wird das neue Widget registriert

dojo.declare("epages.cartridges.de_epages.product.widget.ProductPickerList", [epages.widget.LocalizedWidget], {
    /**
     * public properties
     */
    tableHead            : ["Name"],   // captions of columns
    columnNames          : ["NameOrAlias"], //object attribute name for each column
    displayCheckbox      : true,       //display a checkbox in front of each item and a check-all checkbox
    requestObjectID      : undefined,  //#Shop.ProductFolder.ID
		maxPagerNumberButtons: 5,					//choose only even numbers

    /**
     * widget settings
     */
    widgetsInTemplate : true,
    templatePath      : dojo.moduleUrl('epages.cartridges.de_epages.product.widget', "templates/ProductPickerList.html"),
    translationName   : dojo.moduleUrl('epages.cartridges.de_epages.product.widget', "templates/translation"),

    /**
     * private properties
     */
    _cols              : 0,
    _pageChangeRequest : {
        'ObjectID'          : '', // Product folder
        'ViewAction'        : 'JSONSearchProducts',
        'WildSearchString'  : '',
        'IsAppointment'     : '',
        'PageSize'          : 10,
        'OrderBy'           : 'NameOrAlias',
        'OrderDesc'         : 0,
        'IsNotSubProduct'   : 1
    },
    _checkAllCheckbox : [], // array of all check-all checkboxes (one item for each page)
    _childsOnPage     : [], // items on the currently visible page
    _pager: {
      currentPage : 0,
      itemCount: 0,
      maxPage: 0,
      bufferedPages : [], // one item for each page of the current search which was already visible
      connects : []
    },

    postMixInProperties: function() {
    	this.inherited("postMixInProperties", arguments);
    	this._cols = this.tableHead.length;
    	// calculate column count of the table and set pager cell to fit it
    	if(this.displayCheckbox) {
    		this._cols++;
    	}
    },

    postCreate: function() {
      // summary: create table column headlines, calculate column count and show an empty page
      this.inherited("postCreate", arguments);
      this._pageChangeRequest.ObjectID = this.requestObjectID;
      dojo.forEach(this.tableHead,function(el){
        var tdNode = document.createElement("td");
        tdNode.innerHTML = el;
        this.tableHeadLine.appendChild(tdNode);
      },this);

      // show an empty page
      this._createVisibleChildren(0);
    },
    requestPage : function(/*Integer*/ page,/*Boolean?*/ isNewSearch){
      // summary: request the content of a page of the current page from server or buffer
      if(!this._pageChangeRequest.ObjectID){
        console.error("Shop.PrductFolder.ID is missing");
        return;
      }
      if(this._pager.bufferedPages[page]){
        // page of the result was displayed before --> load saved page
        this._childsOnPage = this._pager.bufferedPages[page];
        this._setPagerButtons({"currentPage":page});
        this._createVisibleChildren(page);
      } else {
        // show loading image over table
        dojo.publish("interactionRestrictor/suspend", ["ProductPickerLoadPage", this.widgetRoot]);
        var json = new epages.io.Json();
        // request search results on current page
        json.loadAsync("?",
                       dojo.hitch(this,this.handleRequest,page),
                       dojo.mixin(this._pageChangeRequest,{'PagerPage': page+1}));
      }
    },
    handleRequest : function(/*Integer*/page,/*Object*/requestResult){
      // summary: set pager values for the requestet page, show pager and load content
      epages.vars.requestResult = requestResult;
      dojo.publish("interactionRestrictor/permit", ["ProductPickerLoadPage"]);
      if(requestResult.error || !requestResult.data) {
        this._setPagerButtons({"itemCount":0,"maxPage":0});
        var errorMessage = "";
        if(requestResult.error.data.Errors.length == 1 &&
           requestResult.error.data.Errors[0].Name == "WildSearchString" &&
           requestResult.error.data.Errors[0].Reason == "STRING_EMPTY"){
           // user simply missed to put a search string in the textbox
           errorMessage = this.translate('noResults');
        } else {
           errorMessage = "An error occured while trying to retrieve search results.";
        }
        this._createfullTableRow(errorMessage);
        return;
      }
      // show pager
      this._setPagerButtons({"currentPage":page,
                             "maxPage":requestResult.data.CountOfPages,
                             "itemCount":requestResult.data.CountOfItems});

      // create table content
      this._childsOnPage = dojo.map(requestResult.data.SearchResults,function(el){
        return {_data:el,_node:{}};
      },this);
      this._createVisibleChildren(page);
    },
    pageUp:function(evt){
        // summary: changes the visible elemnts by paging one page up
    	dojo.stopEvent(evt);
      if(this._pager.currentPage+1 != this._pager.maxPage){
        var page = this._pager.currentPage + 1;
        this.requestPage(page);
      }
    },

    pageDown:function(evt){
        // summary: changes the visible elemnts by paging one page down
    	dojo.stopEvent(evt);
      if(this._pager.currentPage > 0){
        var page = this._pager.currentPage - 1;
        this.requestPage(page);
      }
    },

    pageTo: function(evt,/*Integer*/ page){
        // summary: changes the visible elemnts by paging to the given page
    	dojo.stopEvent(evt);
      if(page >= 0 && page < this._pager.maxPage){
        this.requestPage(page);
      }
    },
    _setPagerButtons: function(/*Object*/pagerValues){
      // summary: create the pager elements and display them
      // example: this._setPagerButtons({"currentPage":0,"maxPage":2,"itemCount":12})
      dojo.mixin(this._pager,pagerValues);
      var pagerHTML = "";
      var linknode = undefined;
      var linkNodePattern = document.createElement("a");
      linkNodePattern.href = "#";

      // clean up
      dojo.forEach(this._pager.connects,function(el){
        dojo.disconnect(el);
      });
      dojo.empty(this.pagerBar);
      // count of items is always displayed
      var node = dojo.create("div",{
        "class"     : "PagerCountOfItems",
        "innerHTML" : this.translate('Count')+': '+this._pager.itemCount
      },this.pagerBar);
      // create the whole page control elements and add them to dom
      if(this._pager.maxPage>1){
        dojo.create("div",{
          "class"     : "PagerAdditionalInfo",
          "innerHTML" : this.translate("Site")+' '+(this._pager.currentPage+1)+' '+this.translate("of")+' '+this._pager.maxPage
        },this.pagerBar);
        //go first and go previous page buttons
        if(this._pager.currentPage == 0){
          dojo.create("span",{
            "innerHTML" : '<i class="Opacity30 Sprite list_ico_s_paging_first" title="'+this.translate("FirstPage")+'"></i>',
            "class"     : "NoLink"
          },this.pagerBar);

          dojo.create("span",{
            innerHTML :'<i class="Opacity30 Sprite list_ico_s_paging_backward" title="'+this.translate("Back")+'"></i>',
            "class"   : "NoLink"
          },this.pagerBar);
        } else {
          linkNode = dojo.attr(linkNodePattern.cloneNode(true),{
            title     : this.translate("FirstPage"),
            innerHTML : '<i class="Sprite list_ico_s_paging_first" title="'+this.translate("FirstPage")+'"></i>'
          });
          this.pagerBar.appendChild(linkNode);
          this._pager.connects.push(dojo.connect(linkNode, 'onclick', this,function(evt){
            this.pageTo(evt,0);
          }));

          linkNode = dojo.attr(linkNodePattern.cloneNode(true),{
            title     : this.translate("Back"),
            innerHTML : '<i class="Sprite list_ico_s_paging_backward" title="'+this.translate("Back")+'"></i>'
          });
          this.pagerBar.appendChild(linkNode);
          this._pager.connects.push(dojo.connect(linkNode, 'onclick', this,'pageDown'));
        }
        // create numbers to navigate to a specific page
        var overhead = Math.floor(this._pager.currentPage+(this.maxPagerNumberButtons+1)/2)-this._pager.maxPage;
        overhead = Math.max(overhead,0);
        var startIndex = Math.floor(this._pager.currentPage-(this.maxPagerNumberButtons-1)/2)-overhead;
        startIndex = Math.max(startIndex,0);
        for(var i=startIndex;i<startIndex+this.maxPagerNumberButtons &&
        										 i<this._pager.maxPage;i++){
          if(i==this._pager.currentPage){
            linkNode = dojo.attr(linkNodePattern.cloneNode(true),{
              "class"     : 'SelectedItem',
              "innerHTML" : '<span>'+(i+1)+'</span>'
            });
            this.pagerBar.appendChild(linkNode);
          } else {
            linkNode = dojo.attr(linkNodePattern.cloneNode(true),"innerHTML",(i+1));
            this.pagerBar.appendChild(linkNode);
            this._pager.connects.push(dojo.connect(linkNode, 'onclick', this,function(evt){
              this.pageTo(evt,parseInt(evt.target.innerHTML)-1);
            }));
          }
        }
        // go next and go last page buttons
        if(this._pager.currentPage == this._pager.maxPage-1){
          dojo.create("span",{
            "class"     : 'NoLink',
            "innerHTML" : '<i class="Opacity30 Sprite list_ico_s_paging_forward" title="'+this.translate("Next")+'"></i>'
          },this.pagerBar);

          dojo.create("span",{
            "class"     : 'NoLink',
            "innerHTML" : '<i class="Opacity30 Sprite list_ico_s_paging_last" title="'+this.translate("LastPage")+'"></i>'
          },this.pagerBar);
        } else {
          linkNode = dojo.attr(linkNodePattern.cloneNode(true),{
            title     : this.translate("Next"),
            innerHTML : '<i class="Sprite list_ico_s_paging_forward" title="'+this.translate("Next")+'"></i>'
          });
          this.pagerBar.appendChild(linkNode);
          this._pager.connects.push(dojo.connect(linkNode, 'onclick', this, "pageUp"));

          linkNode = dojo.attr(linkNodePattern.cloneNode(true),{
            title     : this.translate("LastPage"),
            innerHTML : '<i class="Sprite list_ico_s_paging_last" title="'+this.translate("LastPage")+'"></i>'
          });
          this.pagerBar.appendChild(linkNode);
          this._pager.connects.push(dojo.connect(linkNode, 'onclick', this,function(evt){
            this.pageTo(evt,this._pager.maxPage-1);
          }));
        }
      }
    },
    _displayCheckAllOnPage : function(/*Integer*/ page){
      // summary: display a checkbox which checks all item checkboxes at once
      dojo.empty(this.checkAllCheckbox);
      // checkbox is only created if it page was not shown before
      if(!this._checkAllCheckbox[page]){
        var inputNode = dojo.create("input",{
          "type"  : "checkbox",
          "value" : "Checkbox",
          "class" : "Checkbox RunButtonTrigger"
        });
        // checkboxes are always widgets
        inputNode = new epages.widget.FormElement({ },inputNode).elementNode;
        this._checkAllCheckbox[page] = inputNode;
        this.connect(inputNode,"onclick", "_setAllVisible");
      }
      this.checkAllCheckbox.appendChild(this._checkAllCheckbox[page]);
    },

		_createfullTableRow : function(/*String*/ message){
			dojo.empty(this.containerNode);
			if(epages.Browser.engine=="MSIE"){
      	dojo.create("tr",{innerHTML:"<td colspan="+this._cols+">"+message+"</td>"},this.containerNode);
    	} else {
    		this.containerNode.innerHTML = "<tr><td colspan="+this._cols+">"+message+"</td>";
    	}
		},
    _createVisibleChildren: function(/*Integer*/ page){
      // summary: creates table rows for the current on this page of list visible children
      // save items and destroy old visible Children
      if(this.displayCheckbox){
        this._displayCheckAllOnPage(page);
      }
      //remove old content
      //dojo.empty(this.containerNode);
      // IE can't handle dojo.empty
      while(this.containerNode.childNodes.length>0){
      	this.containerNode.removeChild(this.containerNode.childNodes[0]);
      }
      // save content for later use
      this._pager.bufferedPages[page] = this._childsOnPage;
      //create visible items
      if(this._childsOnPage.length == 0){
      	this._createfullTableRow(this.translate('noResults'));
      } else {
        for( var i=0,iLength=this._childsOnPage.length ; i<iLength ; i++ ) {
          var elm = this._childsOnPage[i];
          if(elm){
            if(!elm._node.trNode){
              // calculate item content
              var contentHTML = "";
              var attr = {};
              if(i%2==0){
              	attr["class"] = "alternate";
              }
              elm._node.trNode = dojo.create("tr",attr);
              // add item content
              var timestamp = (new Date()).getTime(); // make it unique
              // column cell content
              for( var j=0,jLength=this.columnNames.length ; j<jLength ; j++ ){
                dojo.create("td",{innerHTML: '<label style="#display:inline-block;#width:300px;" for="checkbox'+elm._data.ObjectID+""+timestamp+'">'+elm._data[this.columnNames[j]]+'</label>'},elm._node.trNode);
              }
              // create checkbox
              var tdNode = dojo.create("td",{
                "class" : "Checkbox"
              },elm._node.trNode,"first");
              elm._node.inputNode = dojo.create("input",{
                "type"  : "text",
                "id"    : "checkbox"+elm._data.ObjectID+""+timestamp,
                "value" : "Checkbox",
                "class" : "Checkbox RunButtonTrigger"
              },tdNode);
              // create checkbox widget
              elm._node.inputNode = new epages.widget.FormElement({ },elm._node.inputNode).elementNode;
            }
            // add item to dom
            this.containerNode.appendChild(elm._node.trNode);
          }
        }
      }
    },

    selectedItems: function () {
      // summary: returns an object array of currently selected items
      var result = {};
      for( var i=0,l=this._pager.bufferedPages.length ; i<l ; i++ ){
        var pageChilds = this._pager.bufferedPages[i];
        // get checked items
        dojo.forEach(pageChilds,function(el){
          if(el._node.inputNode.checked){
            result[el._data.ObjectID]=el._data;
          }
        });
      }
      return result; // Object[]
    },

    _setCheckedStatus: function(/*FormElement*/ input,/*boolean*/ checked,/*boolean?*/skipHighlight) {
      // summary: sets checked status on input field and highlights changes
      var statusChanged = input.checked != checked;
      input.checked = checked;
      // needed that for the ContentList widget (row selection)
      if($$(input.id)) {
        $$(input.id).setChecked(checked);
      }
      if(!skipHighlight) {
        // always remove highlight!
        if(checked && statusChanged) {
          dojo.addClass(input.parentNode.parentNode, "RowSelected");
        }else {
          dojo.removeClass(input.parentNode.parentNode, "RowSelected");
        }
      }
    },

    _setAllVisible: function(/*Object*/ evt) {
      // summary: sets all currently shown item checkboxes to the
      // same checked-state as the check-all checkbox
      var checked = evt.target.checked;
      var items = this._childsOnPage;
      for( var i=0,iLength=items.length ; i<iLength ; i++ ) {
        var item = items[i];
        this._setCheckedStatus(item._node.inputNode,checked);
      }
    },

    uncheckAll : function(){
      // summary: remove checked flag from all checkbox widgets on the widget
      // remove checked from check-all checkboxes
      dojo.forEach(this._checkAllCheckbox,function(el){
        this._setCheckedStatus(el, false,true);
      },this);
      // remove checked from item checkboxes
      for( var i=0,l=this._pager.bufferedPages.length ; i<l ; i++ ){
        var pageChilds = this._pager.bufferedPages[i];
        dojo.forEach(pageChilds,function(el){
          this._setCheckedStatus(el._node.inputNode, false);
        },this);
      }
    },
    startSearch : function(/*String*/searchString,/*String*/isAppointment){
      // summary: start search process and show the first page
      // initialize values
      this._pager.bufferedPages = [];
      this._checkAllCheckbox = [];
      this._pageChangeRequest.WildSearchString = searchString;
      this._pageChangeRequest.IsAppointment = isAppointment;
      this.requestPage(0,true);
    }
  }
);