/**
 * CPV code handling
 * Copyright (C) 2006 CC Open Computer Systems Ltd.
 * Author: Grzegorz Kaczor
 */
/* @include util.js */
/* @include algutil.js */
/* @include cpv_codes_data.js */

/* include util.js before */
/* include algutil.js before */
/* include cpv_codes_data.js before */

function cpv_find_description(cpv_code) {
  var dIdx = algutil_bsearch(t_cpv_codes_ids,''+cpv_code);
  if (dIdx < 0) return '';
  return t_cpv_codes_descriptions[dIdx];
}

function makeCPVDots(cpvValue) {
  if (cpvValue.length < 8) return cpvValue;
  return cpvValue.substring(0,2) + '.' + cpvValue.substring(2,4) + '.' + cpvValue.substring(4,6) + '.' + cpvValue.substring(6,8);
}

/**
 * returns subrange of the current CPV code
 * results are placed in the id_arr and desc_arr
 * the arrays are cleaned before returning result
 * to get a list of top ranges pass null as cpv_code
 */
function cpv_get_range(cpv_code,id_arr,desc_arr) {
  id_arr.length = 0;
  desc_arr.length = 0;
  var retcnt = 0;

  /* get top ranges */
    /* here we use a trick - it may be faster to perform binary search
  100 times which is about 100*log(8500) = 1300 comparisons
  then to perform a linear search (8500 comparisons)
    */

  if (!cpv_code) {
    cpv_code = 0;
  }

  cpv_code = integer_to_string(cpv_code,8);

  /* now count the number of zeros at the end */
  var idx = cpv_code.length-1;
  while (idx >= 0 && cpv_code.charAt(idx) == '0') idx--;
  var cnt = ((cpv_code.length-idx-1)>>1)<<1;
  /* notice - cnt is even now */

  if (cnt == 0) {
    var desc = cpv_find_description(cpv_code);
    if (desc) {
      id_arr[id_arr.length] = cpv_code;
      desc_arr[desc_arr.length] = desc;
      return 1;
    }
    else {
      return 0; /* not found */
    }
  }

  var prefix = cpv_code.substring(0,cpv_code.length-cnt);
  var suffix = '';
  var i;
  for (i = 0; i < cnt-2; i++) {
    suffix += '0';
  }

  if (cnt == 8) {
    id_arr[id_arr.length] = '00000000';
    desc_arr[desc_arr.length] = 'Wszystkie kody CPV';
  }

  /* and append CPVs */
  for (i = 0; i < 100; i++) {
    var code = prefix + integer_to_string(i,2) + suffix;
    var desc = cpv_find_description(code);
    if (desc) {
      id_arr[id_arr.length] = code;
      desc_arr[desc_arr.length] = desc;
      retcnt++;
    }
  }

  return cnt;
}

function cpv_clicked_on_menu( cpvCode, key ) {

  var menu = elid('item_'+cpvCode);

  if (!menu) {
    return false;
  }

  cpv_write_level( key, menu );

}

function cpv_clicked_on_item( cpvCode, key ) {

  var field = cpv_get_selector( key )['input'];

  if (field.value) field.value = field.value + ', ';
  field.value = field.value + makeCPVDots(cpvCode);
}

var cpvSelectors = new Object;

function addLinkClicked() {
  cpv_clicked_on_item( this.getAttribute('cpv_code'), this.getAttribute('s_key') );
  return false;
}

function expLinkClicked() {
  cpv_clicked_on_menu( this.getAttribute('cpv_code'), this.getAttribute('s_key') );
  return false;
}

function cpv_write_level( key, listControl ) {

  var doc = cpv_get_selector( key )['document'];
  if (!doc) return false;

  if (listControl.expanded) {

    // remove all children
    var first = listControl.firstChild;
    var ost = listControl.lastChild;
    while (ost) {
      listControl.removeChild(ost);
      ost = listControl.lastChild;
    }
    listControl.expanded = false;
    listControl.marked = false;
    listControl.className = listControl.oldClassName;

    listControl.appendChild(first);
  }
  else {
    // expand - print
    if (!listControl.cpv) {
      listControl.cpv = '00000000';
      listControl.setAttribute('id','item_00000000');
    }
    var ids = new Array();
    var descs = new Array();
    var level = cpv_get_range(listControl.cpv,ids,descs);
    for (var i = 1; i < ids.length; i++) {

      var classSuffix = '';
      if (i % 2) classSuffix = '_odd';
      else classSuffix = '_even';

      /*var onClickAction_Add = "cpv_clicked_on_item('"+ids[i]+"','"+key+"'); return false;";*/

      /*var onClickAction_Expand = "cpv_clicked_on_menu('"+ids[i]+"','"+key+"'); return false;";*/

      var newListCtrl = false;
      var liCtrl = false;
      if (t_cpv_codes_leaves['_'+ids[i]]) {
        newListCtrl = doc.createElement('li');
        newListCtrl.className = 'cpv_list_item' + classSuffix;
        newListCtrl.cpv = ids[i];
        newListCtrl.expandable = false;
//         liCtrl = doc.createElement('li');
//         liCtrl.className = 'cpv_list_liwrapper';
//         liCtrl.appendChild(newListCtrl);
        liCtrl = newListCtrl;
      }
      else {

        newListCtrl = doc.createElement('ul');
        newListCtrl.className = 'cpv_list_menu' + classSuffix;
        newListCtrl.cpv = ids[i];
        newListCtrl.expanded = false;
        newListCtrl.expandable = true;
        liCtrl = doc.createElement('li');
        liCtrl.className = 'cpv_list_liwrapper';
        liCtrl.appendChild(newListCtrl);
      }
      newListCtrl.setAttribute('id','item_'+ids[i]);

      var innerText = doc.createElement('span');
      innerText.className = 'cpv_list_item_span';

      var expButton = doc.createElement('span');
      expButton.className = 'cpv_list_expbutton';

      if (newListCtrl.expandable) {

        var expLink = doc.createElement('a');
        expLink.className = 'cpv_list_explink';
        expLink.setAttribute('href','#');
        expLink.appendChild(doc.createTextNode(' @ '));
        expLink.setAttribute('s_key',key);
        expLink.setAttribute('cpv_code',ids[i]);
        expLink.onclick = expLinkClicked;
        expButton.appendChild(expLink);

      }
      else {
        expButton.appendChild(doc.createTextNode(" "));
      }
      innerText.appendChild(expButton);

      /* add button */
      var addButton = doc.createElement('span');
      addButton.className = 'cpv_list_addbutton';

      var addLink = doc.createElement('a');
      addLink.className = 'cpv_list_addlink';
      addLink.setAttribute('href','#');
      addLink.appendChild(doc.createTextNode(' + '));

      addLink.setAttribute('s_key',key);
      addLink.setAttribute('cpv_code',ids[i]);
      addLink.onclick = addLinkClicked;
      addButton.appendChild(addLink);

      innerText.appendChild(addButton);

      var cpvText = doc.createElement('span');
      cpvText.className = 'cpv_list_cpvid';
      cpvText.appendChild(doc.createTextNode(makeCPVDots(ids[i])));
      innerText.appendChild(cpvText);

      cpvText = doc.createElement('span');
      cpvText.className = 'cpv_list_cpvdesc';
      cpvText.appendChild(doc.createTextNode(descs[i]));
      innerText.appendChild(cpvText);

      newListCtrl.appendChild(innerText);

      listControl.appendChild(liCtrl);

    }

    if ( ids.length > 1 && (listControl.className == 'cpv_list_menu_odd' ||
      listControl.className == 'cpv_list_menu_even')) {
      listControl.oldClassName = listControl.className;
      listControl.className = 'cpv_list_menu_marked';
      listControl.expanded = true;
      listControl.marked = true;
    }
  }

}

function cpv_compute_level( cpvCode ) {
  if (!cpvCode) {
    cpvCode = 0;
  }

  cpvCode = integer_to_string(cpvCode,8);

  /* now count the number of zeros at the end */
  var idx = cpvCode.length-1;
  while (idx >= 0 && cpvCode.charAt(idx) == '0') idx--;
  return ((cpvCode.length-idx-1)>>1)<<1;

}

function cpv_get_level_part( cpvCode, level ) {

  if (level < 0 || level > 8) return cpvCode;

  return cpvCode.substring(0,8-level)+'00000000'.substring(0,level);
}

function cpv_mark_elem( elem, key ) {

  if (!elem) return false;

  if (elem.marked) {
    return true;
  }

  if (elem.expandable) {
    cpv_write_level( key, elem );
  }
  else {
    elem.oldClassName = elem.className;
    elem.className = elem.className + '_marked';
    elem.marked = true;
  }
  return true;
}

function cpv_unmark_elem( elem, key ) {
  if (!elem) return false;

  if (!elem.marked) return true;

  if (elem.expandable) {
    cpv_write_level( key, elem );
  }
  else {
    elem.className = elem.oldClassName;
    elem.marked = false;
  }
  return true;
}

function cpv_mark_path( cpvCode, key ) {

  var level = cpv_compute_level( cpvCode );

  var ilevel = 6;

  while (ilevel > level) {
    var parentCpv = cpv_get_level_part( cpvCode, ilevel );
    cpv_mark_elem( elid( 'item_'+parentCpv ), key );
    ilevel -= 2;
  }

  cpv_mark_elem( elid( 'item_'+cpvCode ), key );
}



function cpv_new_selector( key ) {

  var sel = new Object;

  sel['level'] = '0';
  sel['key'] = key;

  cpvSelectors[ key ] = sel;

  return sel;
}

var mySelector = false;

function cpv_get_selector( key ) {

  if (mySelector) return mySelector;

  if (cpvSelectors[ key ]) {
    return cpvSelectors[ key ];
  }
  else {
    return cpv_new_selector( key );
  }

}

function cpv_show_selection_window( baseURL, windowName, resultInput, key ) {

  var sel = cpv_get_selector( key );

  if (!sel) {
    alert('Nie udało się utworzenie obiektu selektora CPV');
    return false;
  }

  sel['input'] = resultInput;
  sel['window_name'] = windowName;
  sel['window'] = window.open( baseURL, windowName, 'alwaysRaised, dependent, height=600px, width=750px, menubar=no, resizable=true, scrollbars, status, titlebar, toolbar=no' );

  return true;
}

var max_results = 100;

function cpv_find_by_keyword( key, keyword, id_arr ) {

  keyword = keyword.toLowerCase();

  for (var i = 0; i < t_cpv_codes_ids.length; i++) {
    var fi = makeCPVDots(t_cpv_codes_ids[i]).toLowerCase().indexOf(keyword);

    if (fi >= 0) {
      id_arr[id_arr.length] = t_cpv_codes_ids[i];
      if (id_arr.length > max_results) break;
    }
  }

  if (id_arr.length > max_results) return id_arr.length;

  for (var i = 0; i < t_cpv_codes_descriptions.length; i++) {
    var fi = t_cpv_codes_descriptions[i].toLowerCase().indexOf(keyword);

    if (fi >= 0) {
      id_arr[id_arr.length] = t_cpv_codes_ids[i];
      if (id_arr.length > max_results) break;
    }
  }

  return id_arr.length;
}

function cpv_mark_by_keyword( key, keyword ) {

  var ids = new Array();
  var descs = new Array();

  // remove current selections and open elements
  cpv_get_range( '00000000', ids, descs );
  for (var i = 0; i < ids.length; i++) {
    cpv_unmark_elem( elid('item_'+ids[i]), key );
  }

  keyword = trim(keyword);

  if (!keyword) return false;

  ids.length = 0;


  cpv_find_by_keyword( key, keyword, ids );

  for (var i = 0; i < ids.length; i++) {
    cpv_mark_path( ids[i], key );
  }

  return true;
}

function cpv_window_initialize( key, doc ) {

  sel = window.opener.cpvSelectors[key];

  if (!sel) return false;

  mySelector = sel;

  sel['document'] = doc;
  sel['hook'] = doc.getElementById('cpv_list_hook');
  if (!sel['hook']) {
    alert('no hook');
  }

  var topMenu = doc.createElement('ul');
  sel['hook'].appendChild(topMenu);
  sel['toplist'] = topMenu;
  topMenu.className = 'cpv_list_menu';
  topMenu.expandable = true;

  cpv_write_level( key, topMenu );

  return true;
}


